def loadSettings(self): self.popup = Settings.get(self._settings_key + '/popup', True, type=bool) self.sound = Settings.get(self._settings_key + '/sound', True, type=bool)
def setActiveMods(mods, keepuimods=True, temporary=True): # uimods works the same as in getActiveMods """ keepuimods: None: Replace all active mods with 'mods' True: Keep the UI mods already activated activated False: Keep only the non-UI mods that were activated activated So set it True if you want to set gameplay mods, and False if you want to set UI mods. temporary: Set this when mods are activated due to joining a game. """ if keepuimods is not None: keepTheseMods = getActiveMods( keepuimods ) # returns the active UI mods if True, the active non-ui mods if False else: keepTheseMods = [] allmods = keepTheseMods + mods logger.debug('setting active Mods: {}'.format([mod.uid for mod in allmods])) s = "active_mods = {\n" for mod in allmods: s += "['%s'] = true,\n" % str(mod.uid) s += "}" if not temporary: global selectedMods logger.debug('selectedMods was: {}'.format(Settings.get('play/mods'))) selectedMods = [str(mod.uid) for mod in allmods] logger.debug('Writing selectedMods: {}'.format(selectedMods)) Settings.set('play/mods', selectedMods) logger.debug('selectedMods written: {}'.format( Settings.get('play/mods'))) try: f = open(PREFSFILENAME, 'r') data = f.read() except: logger.info("Couldn't read the game.prefs file") return False else: f.close() if re.search("active_mods\s*=\s*{.*?}", data, re.S): data = re.sub("active_mods\s*=\s*{.*?}", s, data, 1, re.S) else: data += "\n" + s try: f = open(PREFSFILENAME, 'w') f.write(data) except: logger.info("Cound't write to the game.prefs file") return False else: f.close() return True
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 = "{}/faf/tutorials/{}".format(Settings.get('content/host'), 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.THEME.icon("games/unknown_map.png") self.client.map_downloader.download_preview( self.mapname, self._map_dl_request) self.setIcon(icon) self.setText( self.FORMATTER_TUTORIAL.format(mapdisplayname=self.mapdisplayname, title=self.tutorial, description=self.description))
def build_argument_list(game_info, port, arguments=None): """ Compiles an argument list to run the game with POpen style process invocation methods. Extends a potentially pre-existing argument list to allow for injection of special parameters """ import client arguments = arguments or [] if '/init' in arguments: raise ValueError("Custom init scripts no longer supported.") # Init file arguments.append('/init') arguments.append('init_{}.lua'.format(game_info.get('featured_mod', 'faf'))) arguments.append('/numgames {}'.format(client.instance.me.number_of_games)) # log file if Settings.get("game/logs", False, type=bool): arguments.append("/log") arguments.append('"' + util.LOG_FILE_GAME + '"') # Disable defunct bug reporter arguments.append('/nobugreport') # live replay arguments.append('/savereplay') arguments.append('"gpgnet://localhost/' + str(game_info['uid']) + "/" + str(game_info['recorder']) + '.SCFAreplay"') # gpg server emulation arguments.append('/gpgnet 127.0.0.1:' + str(port)) return arguments
def build_argument_list(game_info, port, arguments=None): """ Compiles an argument list to run the game with POpen style process invocation methods. Extends a potentially pre-existing argument list to allow for injection of special parameters """ import client arguments = arguments or [] if '/init' in arguments: raise ValueError("Custom init scripts no longer supported.") # Init file arguments.append('/init') arguments.append('init_{}.lua'.format(game_info.get('featured_mod', 'faf'))) arguments.append('/numgames {}'.format(client.instance.me.number_of_games)) # log file if Settings.get("game/logs", False, type=bool): arguments.append("/log") arguments.append('"' + util.LOG_FILE_GAME + '"') # Disable defunct bug reporter arguments.append('/nobugreport') # live replay arguments.append('/savereplay') arguments.append('"gpgnet://localhost/' + str(game_info['uid']) + "/" + str(game_info['recorder']) + '.SCFAreplay"') # gpg server emulation arguments.append('/gpgnet 127.0.0.1:' + str(port)) return arguments
def on_join(self, c, e): channel = e.target() # If we're joining, we need to open the channel for us first. if channel not in self.channels: newch = Channel(self, channel, self._chatters, self._me) if channel.lower() in self.crucialChannels: self.add_channel( channel, newch, 1) # CAVEAT: This is assumes a server tab exists. self.client.localBroadcast.connect(newch.print_raw) newch.print_announcement("Welcome to Forged Alliance Forever!", "red", "+3") wiki_link = Settings.get("WIKI_URL") wiki_msg = "Check out the wiki: {} for help with common issues.".format( wiki_link) newch.print_announcement(wiki_msg, "white", "+1") newch.print_announcement("", "black", "+1") newch.print_announcement("", "black", "+1") else: self.add_channel(channel, newch) if channel.lower( ) in self.crucialChannels: # Make the crucial channels not closeable, and make the last one the active one self.setCurrentWidget(self.channels[channel]) self.tabBar().setTabButton(self.currentIndex(), QtWidgets.QTabBar.RightSide, None) name, _id, elevation, hostname = parse_irc_source(e.source()) self._add_chatter(name, hostname) self._add_chatter_channel(self._chatters[name], elevation, channel, True)
def loadSettings(self): self.mode = Settings.get(self._settings_key+'/mode', 'friends') if self.mode == 'friends': self.radioButtonFriends.setChecked(True) else: self.radioButtonAll.setChecked(True) self.parent.mode = self.mode
def loadSettings(self): self.mode = Settings.get(self._settings_key + '/mode', 'friends') if self.mode == 'friends': self.radioButtonFriends.setChecked(True) else: self.radioButtonAll.setChecked(True) self.parent.mode = self.mode
def loadSettings(self): self.enabled = Settings.get('notifications/enabled', True, type=bool) self.popup_lifetime = Settings.get('notifications/popup_lifetime', 5, type=int) self.popup_position = NotificationPosition( Settings.get('notifications/popup_position', NotificationPosition.BOTTOM_RIGHT.value, type=int)) self.ingame_notifications = IngameNotification( Settings.get('notifications/ingame', IngameNotification.ENABLE, type=int)) self.nsEnabled.setChecked(self.enabled) self.nsPopLifetime.setValue(self.popup_lifetime) self.nsPositionComboBox.setCurrentIndex(self.popup_position.value) self.nsIngameComboBox.setCurrentIndex(self.ingame_notifications.value)
def AdminUserErrorDialog(): from config import Settings ignore_admin = Settings.get("client/ignore_admin", False, bool) if not ignore_admin: box = QtWidgets.QMessageBox() box.setText( "FAF should not be run as an administrator!<br><br>This probably means you need " "to fix the file permissions in C:\\ProgramData.<br>Proceed at your own risk." ) box.setStandardButtons(QtWidgets.QMessageBox.Ignore | QtWidgets.QMessageBox.Close) box.setIcon(QtWidgets.QMessageBox.Critical) box.setWindowTitle("FAF privilege error") if box.exec_() == QtWidgets.QMessageBox.Ignore: Settings.set("client/ignore_admin", True)
def reloadView(self): if self.loaded: return self.loaded = True self.ui.setVisible(False) # If a local theme CSS exists, skin the WebView with it if util.THEME.themeurl("vault/style.css"): injectWebviewCSS(self.ui.page(), util.THEME.readstylesheet("vault/style.css")) ROOT = Settings.get('content/host') url = QtCore.QUrl(ROOT) url.setPath("/faf/vault/maps_qt5.php") query = QtCore.QUrlQuery(url.query()) query.addQueryItem('username', self.client.login) query.addQueryItem('pwdhash', self.client.password) url.setQuery(query) self.ui.setUrl(url)
def busy_entered(self): # Don't display things when we're not logged in # FIXME - one day we'll have more obvious points of entry if self.client.state != client.ClientState.LOGGED_IN: return if self.selected_player is None: self.selected_player = self.client.players[self.client.login] if self.selected_player.league is not None: self.leagues.setCurrentIndex(self.selected_player.league - 1) else: self.leagues.setCurrentIndex(5) # -> 5 = direct to Ladder Ratings if self.selected_player_loaded: return self.webview.setVisible(False) self.webview.setUrl( QtCore.QUrl( "{}/faf/leaderboards/read-leader.php?board=1v1&username={}". format(Settings.get('content/host'), self.selected_player.login))) self.selected_player_loaded = True
class Updater(QtCore.QObject): """ This is the class that does the actual installation work. """ # Network configuration SOCKET = 9001 HOST = Settings.get('lobby/host') TIMEOUT = 20 #seconds # Return codes to expect from run() RESULT_SUCCESS = 0 #Update successful RESULT_NONE = -1 #Update operation is still ongoing RESULT_FAILURE = 1 #An error occured during updating RESULT_CANCEL = 2 #User cancelled the download process RESULT_ILLEGAL = 3 #User has the wrong version of FA RESULT_BUSY = 4 #Server is currently busy RESULT_PASS = 5 #User refuses to update by canceling the wizard def __init__(self, featured_mod, version=None, modversions=None, sim=False, silent=False, *args, **kwargs): """ Constructor """ QtCore.QObject.__init__(self, *args, **kwargs) self.filesToUpdate = [] self.lastData = time.time() self.featured_mod = featured_mod self.version = version self.modversions = modversions self.sim = sim self.modpath = None self.blockSize = 0 self.updateSocket = QtNetwork.QTcpSocket() self.updateSocket.setSocketOption(QtNetwork.QTcpSocket.KeepAliveOption, 1) self.updateSocket.setSocketOption(QtNetwork.QTcpSocket.LowDelayOption, 1) self.result = self.RESULT_NONE self.destination = None self.silent = silent self.progress = QtGui.QProgressDialog() if self.silent: self.progress.setCancelButton(None) else: self.progress.setCancelButtonText("Cancel") self.progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) self.progress.setAutoClose(False) self.progress.setAutoReset(False) self.progress.setModal(1) self.progress.setWindowTitle("Updating %s" % str(self.featured_mod).upper()) self.bytesToSend = 0 def run(self, *args, **kwargs): clearLog() log("Update started at " + timestamp()) log("Using appdata: " + util.APPDATA_DIR) self.progress.show() QtGui.QApplication.processEvents() #Actual network code adapted from previous version self.progress.setLabelText("Connecting to update server...") self.updateSocket.error.connect(self.handleServerError) self.updateSocket.readyRead.connect(self.readDataFromServer) self.updateSocket.disconnected.connect(self.disconnected) self.updateSocket.error.connect(self.errored) self.updateSocket.connectToHost(self.HOST, self.SOCKET) while not (self.updateSocket.state() == QtNetwork.QAbstractSocket. ConnectedState) and self.progress.isVisible(): QtGui.QApplication.processEvents() if not self.progress.wasCanceled(): log("Connected to update server at " + timestamp()) self.doUpdate() self.progress.setLabelText("Cleaning up.") self.updateSocket.close() self.progress.close() else: log("Cancelled connecting to server.") self.result = self.RESULT_CANCEL log("Update finished at " + timestamp()) return self.result def fetchFile(self, url, toFile): try: progress = QtGui.QProgressDialog() progress.setCancelButtonText("Cancel") progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) progress.setAutoClose(True) progress.setAutoReset(False) req = urllib2.Request(url, headers={'User-Agent': "FAF Client"}) downloadedfile = urllib2.urlopen(req) meta = downloadedfile.info() #Fix for #241, sometimes the server sends an error and no content-length. file_size = int(meta.getheaders("Content-Length")[0]) progress.setMinimum(0) progress.setMaximum(file_size) progress.setModal(1) progress.setWindowTitle("Downloading Update") label = QtGui.QLabel() label.setOpenExternalLinks(True) progress.setLabel(label) progress.setLabelText('Downloading FA file : <a href="' + url + '">' + url + '</a><br/>File size: ' + str(int(file_size / 1024 / 1024)) + ' MiB') progress.show() #Download the file as a series of up to 4 KiB chunks, then uncompress it. output = tempfile.NamedTemporaryFile(mode='w+b', delete=False) file_size_dl = 0 block_sz = 4096 while progress.isVisible(): QtGui.QApplication.processEvents() read_buffer = downloadedfile.read(block_sz) if not read_buffer: break file_size_dl += len(read_buffer) output.write(read_buffer) progress.setValue(file_size_dl) output.flush() os.fsync(output.fileno()) output.close() shutil.move(output.name, toFile) if (progress.value() == file_size) or progress.value() == -1: logger.debug("File downloaded successfully.") return True else: QtGui.QMessageBox.information(None, "Aborted", "Download not complete.") logger.warn("File download not complete.") return False except: logger.error("Updater error: ", exc_info=sys.exc_info()) QtGui.QMessageBox.information( None, "Download Failed", "The file wasn't properly sent by the server. <br/><b>Try again later.</b>" ) return False def updateFiles(self, destination, filegroup): """ Updates the files in a given file group, in the destination subdirectory of the Forged Alliance path. If existing=True, the existing contents of the directory will be added to the current self.filesToUpdate list. """ QtGui.QApplication.processEvents() self.progress.setLabelText("Updating files: " + filegroup) self.destination = destination self.writeToServer("GET_FILES_TO_UPDATE", filegroup) self.waitForFileList() #Ensure our list is unique self.filesToUpdate = list(set(self.filesToUpdate)) targetdir = os.path.join(util.APPDATA_DIR, destination) if not os.path.exists(targetdir): os.makedirs(targetdir) for fileToUpdate in self.filesToUpdate: md5File = util.md5( os.path.join(util.APPDATA_DIR, destination, fileToUpdate)) if md5File == None: if self.version: if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or filegroup == "FAF" or filegroup == "FAFGAMEDATA": self.writeToServer("REQUEST_VERSION", destination, fileToUpdate, str(self.version)) else: self.writeToServer("REQUEST_MOD_VERSION", destination, fileToUpdate, json.dumps(self.modversions)) else: self.writeToServer("REQUEST_PATH", destination, fileToUpdate) else: if self.version: if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or filegroup == "FAF" or filegroup == "FAFGAMEDATA": self.writeToServer("PATCH_TO", destination, fileToUpdate, md5File, str(self.version)) else: self.writeToServer("MOD_PATCH_TO", destination, fileToUpdate, md5File, json.dumps(self.modversions)) else: self.writeToServer("UPDATE", destination, fileToUpdate, md5File) self.waitUntilFilesAreUpdated() def waitForSimModPath(self): """ A simple loop that waits until the server has transmitted a sim mod path. """ self.lastData = time.time() self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) while self.modpath == None: if self.progress.wasCanceled(): raise UpdaterCancellation( "Operation aborted while waiting for sim mod path.") if self.result != self.RESULT_NONE: raise UpdaterFailure( "Operation failed while waiting for sim mod path.") if time.time() - self.lastData > self.TIMEOUT: raise UpdaterTimeout( "Operation timed out while waiting for sim mod path.") QtGui.QApplication.processEvents() def waitForFileList(self): """ A simple loop that waits until the server has transmitted a file list. """ self.lastData = time.time() self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) while len(self.filesToUpdate) == 0: if self.progress.wasCanceled(): raise UpdaterCancellation( "Operation aborted while waiting for file list.") if self.result != self.RESULT_NONE: raise UpdaterFailure( "Operation failed while waiting for file list.") if time.time() - self.lastData > self.TIMEOUT: raise UpdaterTimeout( "Operation timed out while waiting for file list.") QtGui.QApplication.processEvents() log("Files to update: [" + ', '.join(self.filesToUpdate) + "]") def waitUntilFilesAreUpdated(self): """ A simple loop that updates the progress bar while the server sends actual file data """ self.lastData = time.time() self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) while len(self.filesToUpdate) > 0: if self.progress.wasCanceled(): raise UpdaterCancellation( "Operation aborted while waiting for data.") if (self.result != self.RESULT_NONE): raise UpdaterFailure( "Operation failed while waiting for data.") if (time.time() - self.lastData > self.TIMEOUT): raise UpdaterTimeout( "Connection timed out while waiting for data.") QtGui.QApplication.processEvents() log("Updates applied successfully.") def prepareBinFAF(self): ''' Creates all necessary files in the binFAF folder, which contains a modified copy of all that is in the standard bin folder of Forged Alliance ''' self.progress.setLabelText("Preparing binFAF...") #now we check if we've got a binFAF folder FABindir = os.path.join(config.Settings.get("ForgedAlliance/app/path"), 'bin') FAFdir = util.BIN_DIR #Try to copy without overwriting, but fill in any missing files, otherwise it might miss some files to update root_src_dir = FABindir root_dst_dir = FAFdir for src_dir, _, files in os.walk(root_src_dir): dst_dir = src_dir.replace(root_src_dir, root_dst_dir) if not os.path.exists(dst_dir): os.mkdir(dst_dir) for file_ in files: src_file = os.path.join(src_dir, file_) dst_file = os.path.join(dst_dir, file_) if not os.path.exists(dst_file): shutil.copy(src_file, dst_dir) st = os.stat(dst_file) os.chmod( dst_file, st.st_mode | stat.S_IWRITE ) # make all files we were considering writable, because we may need to patch them def doUpdate(self): """ The core function that does most of the actual update work.""" try: if self.sim: self.writeToServer("REQUEST_SIM_PATH", self.featured_mod) self.waitForSimModPath() if self.result == self.RESULT_SUCCESS: if modvault.downloadMod(self.modpath): self.writeToServer("ADD_DOWNLOAD_SIM_MOD", self.featured_mod) else: #Prepare FAF directory & all necessary files self.prepareBinFAF() #Update the mod if it's requested if self.featured_mod == "faf" or self.featured_mod == "ladder1v1": #HACK - ladder1v1 "is" FAF. :-) self.updateFiles("bin", "FAF") self.updateFiles("gamedata", "FAFGAMEDATA") pass elif self.featured_mod: self.updateFiles("bin", "FAF") self.updateFiles("gamedata", "FAFGAMEDATA") self.updateFiles("bin", self.featured_mod) self.updateFiles("gamedata", self.featured_mod + "Gamedata") except UpdaterTimeout, e: log("TIMEOUT: {}".format(e)) self.result = self.RESULT_FAILURE except UpdaterCancellation, e: log("CANCELLED: {}".format(e)) self.result = self.RESULT_CANCEL
def loadSettings(self): self.popup = Settings.get(self._settings_key + '/popup', True, type=bool) self.sound = Settings.get(self._settings_key + '/sound', True, type=bool)
class SecondaryServer(QtCore.QObject): # Network configuration HOST = "lobby." + Settings.get('host') TIMEOUT = 5 # seconds # Return codes to expect from run() RESULT_SUCCESS = 0 # successful RESULT_NONE = -1 # operation is still ongoing RESULT_FAILURE = 1 # an error occured RESULT_CANCEL = 2 # User cancelled RESULT_BUSY = 4 # Server is currently busy RESULT_PASS = 5 # User refuses to update by canceling def __init__(self, name, socket, dispatcher, *args, **kwargs): """ Constructor """ QtCore.QObject.__init__(self, *args, **kwargs) self.name = name logger = logging.getLogger("faf.secondaryServer.%s" % self.name) logger.info("Instantiating secondary server.") self.logger = logger self.socketPort = socket self.dispatcher = dispatcher self.command = None self.message = None self.blockSize = 0 self.serverSocket = QtNetwork.QTcpSocket() self.serverSocket.error.connect(self.handleServerError) self.serverSocket.readyRead.connect(self.readDataFromServer) self.serverSocket.connected.connect(self.send_pending) self.invisible = False self._requests = [] def setInvisible(self): self.invisible = True def send(self, command, *args, **kwargs): """ actually do the settings """ self._requests += [{ 'command': command, 'args': args, 'kwargs': kwargs }] self.logger.info("Pending requests: {}".format(len(self._requests))) if not self.serverSocket.state( ) == QtNetwork.QAbstractSocket.ConnectedState: self.logger.info("Connecting to {} {}:{}".format( self.name, self.HOST, self.socketPort)) self.serverSocket.connectToHost(self.HOST, self.socketPort) else: self.send_pending() def send_pending(self): for req in self._requests: self.send_request(req['command'], req['args'], req['kwargs']) self._requests = [] def send_request(self, command, *args, **kwargs): self.sendJson(command) def sendJson(self, message): data = json.dumps(message) logger.debug("Outgoing JSON Message: " + data) self.writeToServer(data) @QtCore.pyqtSlot() def readDataFromServer(self): ins = QtCore.QDataStream(self.serverSocket) ins.setVersion(QtCore.QDataStream.Qt_4_2) while not ins.atEnd(): if self.blockSize == 0: if self.serverSocket.bytesAvailable() < 4: return self.blockSize = ins.readUInt32() if self.serverSocket.bytesAvailable() < self.blockSize: return action = ins.readQString() self.process(action, ins) self.blockSize = 0 def writeToServer(self, action, *args, **kw): block = QtCore.QByteArray() out = QtCore.QDataStream(block, QtCore.QIODevice.ReadWrite) out.setVersion(QtCore.QDataStream.Qt_4_2) out.writeUInt32(0) out.writeQString(action) for arg in args: if type(arg) is int: out.writeInt(arg) elif isinstance(arg, str): out.writeQString(arg) elif type(arg) is float: out.writeFloat(arg) elif type(arg) is list: out.writeQVariantList(arg) else: out.writeQString(str(arg)) out.device().seek(0) out.writeUInt32(block.size() - 4) self.bytesToSend = block.size() - 4 self.serverSocket.write(block) def process(self, action, stream): self.receiveJSON(action, stream) def receiveJSON(self, data_string, stream): """ A fairly pythonic way to process received strings as JSON messages. """ message = json.loads(data_string) logger.debug("answering from server :" + str(message["command"])) self.dispatcher.dispatch(message) @QtCore.pyqtSlot('QAbstractSocket::SocketError') def handleServerError(self, socketError): """ Simple error handler that flags the whole operation as failed, not very graceful but what can you do... """ if socketError == QtNetwork.QAbstractSocket.RemoteHostClosedError: log("FA Server down: The server is down for maintenance, please try later." ) elif socketError == QtNetwork.QAbstractSocket.HostNotFoundError: log("Connection to Host lost. Please check the host name and port settings." ) elif socketError == QtNetwork.QAbstractSocket.ConnectionRefusedError: log("The connection was refused by the peer.") else: log("The following error occurred: %s." % self.serverSocket.errorString())
def tech_support(self): QtGui.QDesktopServices().openUrl(QtCore.QUrl(Settings.get("HELP_URL")))
# Initialize logging system import logging from PyQt5.QtNetwork import QNetworkAccessManager from enum import IntEnum from config import Settings logger = logging.getLogger(__name__) # logger.setLevel(logging.DEBUG) # Initialize all important globals LOBBY_HOST = Settings.get('lobby/host') LOBBY_PORT = Settings.get('lobby/port') LOCAL_REPLAY_PORT = Settings.get('lobby/relay/port') class ClientState(IntEnum): """ Various states the client can be in. """ SHUTDOWN = -666 # Going... DOWN! DISCONNECTED = -2 CONNECTING = -1 NONE = 0 CONNECTED = 1 LOGGED_IN = 2 from ._clientwindow import ClientWindow
def on_new_account(self): QtGui.QDesktopServices.openUrl( QtCore.QUrl(Settings.get("CREATE_ACCOUNT_URL")))
from PyQt4 import QtCore, QtNetwork, QtGui import os import logging import util import fa import json import time from config import Settings INTERNET_REPLAY_SERVER_HOST = Settings.get('replay_server/host') INTERNET_REPLAY_SERVER_PORT = Settings.get('replay_server/port') from . import DEFAULT_LIVE_REPLAY from . import DEFAULT_RECORD_REPLAY class ReplayRecorder(QtCore.QObject): """ This is a simple class that takes all the FA replay data input from its inputSocket, writes it to a file, and relays it to an internet server via its relaySocket. """ __logger = logging.getLogger(__name__) def __init__(self, parent, local_socket, *args, **kwargs): QtCore.QObject.__init__(self, *args, **kwargs) self.parent = parent self.inputSocket = local_socket self.inputSocket.setSocketOption(QtNetwork.QTcpSocket.KeepAliveOption, 1)
def send_the_orcs(): route = Settings.get('mordor/host') if _id != -1: QtGui.QDesktopServices.openUrl(QUrl("{}/users/{}".format(route, _id))) else: QtGui.QDesktopServices.openUrl(QUrl("{}/users/{}".format(route, name)))
class Updater(QtCore.QObject, ConnectionHandler): """ This is the class that does the actual installation work. """ # Network configuration SOCKET = 9001 HOST = Settings.get('lobby/host') TIMEOUT = 20 # seconds # Return codes to expect from run() RESULT_SUCCESS = 0 # Update successful RESULT_NONE = -1 # Update operation is still ongoing RESULT_FAILURE = 1 # An error occured during updating RESULT_CANCEL = 2 # User cancelled the download process RESULT_ILLEGAL = 3 # User has the wrong version of FA RESULT_BUSY = 4 # Server is currently busy RESULT_PASS = 5 # User refuses to update by canceling the wizard def __init__(self, featured_mod, version=None, modversions=None, sim=False, silent=False, *args, **kwargs): """ Constructor """ QtCore.QObject.__init__(self, *args, **kwargs) self.filesToUpdate = [] self.updatedFiles = [] self.connection = UpdateConnection(self, self.HOST, self.SOCKET) self.lastData = time.time() self.featured_mod = featured_mod self.version = version self.modversions = modversions self.sim = sim self.modpath = None self.result = self.RESULT_NONE self.destination = None self.silent = silent self.progress = QtWidgets.QProgressDialog() if self.silent: self.progress.setCancelButton(None) else: self.progress.setCancelButtonText("Cancel") self.progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) self.progress.setAutoClose(False) self.progress.setAutoReset(False) self.progress.setModal(1) self.progress.setWindowTitle("Updating %s" % str(self.featured_mod).upper()) self.bytesToSend = 0 def run(self, *args, **kwargs): clearLog() log("Update started at " + timestamp()) log("Using appdata: " + util.APPDATA_DIR) self.progress.show() QtWidgets.QApplication.processEvents() # Actual network code adapted from previous version self.progress.setLabelText("Connecting to update server...") self.connection.connect() while not (self.connection.connected()) and self.progress.isVisible(): QtWidgets.QApplication.processEvents() if not self.progress.wasCanceled(): log("Connected to update server at " + timestamp()) self.doUpdate() self.progress.setLabelText("Cleaning up.") self.connection.disconnect() self.progress.close() else: log("Cancelled connecting to server.") self.result = self.RESULT_CANCEL log("Update finished at " + timestamp()) return self.result def fetchFile(self, url, toFile): try: logger.info('Updater: Downloading {}'.format(url)) progress = QtWidgets.QProgressDialog() progress.setCancelButtonText("Cancel") progress.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) progress.setAutoClose(True) progress.setAutoReset(False) req = urllib.request.Request(url, headers={'User-Agent': "FAF Client"}) downloadedfile = urllib.request.urlopen(req) meta = downloadedfile.info() # Fix for #241, sometimes the server sends an error and no content-length. file_size = int(meta.get_all("Content-Length")[0]) progress.setMinimum(0) progress.setMaximum(file_size) progress.setModal(1) progress.setWindowTitle("Downloading Update") label = QtWidgets.QLabel() label.setOpenExternalLinks(True) progress.setLabel(label) progress.setLabelText('Downloading FA file : <a href="' + url + '">' + url + '</a><br/>File size: ' + str(int(file_size / 1024 / 1024)) + ' MiB') progress.show() # Download the file as a series of up to 4 KiB chunks, then uncompress it. output = tempfile.NamedTemporaryFile(mode='w+b', delete=False) file_size_dl = 0 block_sz = 4096 while progress.isVisible(): QtWidgets.QApplication.processEvents() if not progress.isVisible(): break read_buffer = downloadedfile.read(block_sz) if not read_buffer: break file_size_dl += len(read_buffer) output.write(read_buffer) progress.setValue(file_size_dl) output.flush() os.fsync(output.fileno()) output.close() shutil.move(output.name, toFile) if (progress.value() == file_size) or progress.value() == -1: logger.debug("File downloaded successfully.") return True else: QtWidgets.QMessageBox.information(None, "Aborted", "Download not complete.") logger.warning("File download not complete.") return False except: logger.error("Updater error: ", exc_info=sys.exc_info()) QtWidgets.QMessageBox.information( None, "Download Failed", "The file wasn't properly sent by the server. " "<br/><b>Try again later.</b>") return False def updateFiles(self, destination, filegroup): """ Updates the files in a given file group, in the destination subdirectory of the Forged Alliance path. If existing=True, the existing contents of the directory will be added to the current self.filesToUpdate list. """ QtWidgets.QApplication.processEvents() self.progress.setLabelText("Updating files: " + filegroup) self.destination = destination self.connection.writeToServer("GET_FILES_TO_UPDATE", filegroup) self.waitForFileList() # Ensure our list is unique self.filesToUpdate = list(set(self.filesToUpdate)) targetdir = os.path.join(util.APPDATA_DIR, destination) if not os.path.exists(targetdir): os.makedirs(targetdir) for fileToUpdate in self.filesToUpdate: md5File = util.md5( os.path.join(util.APPDATA_DIR, destination, fileToUpdate)) if md5File is None: if self.version: if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or \ filegroup == "FAF" or filegroup == "FAFGAMEDATA": self.connection.writeToServer("REQUEST_VERSION", destination, fileToUpdate, str(self.version)) else: self.connection.writeToServer( "REQUEST_MOD_VERSION", destination, fileToUpdate, json.dumps(self.modversions)) else: self.connection.writeToServer("REQUEST_PATH", destination, fileToUpdate) else: if self.version: if self.featured_mod == "faf" or self.featured_mod == "ladder1v1" or \ filegroup == "FAF" or filegroup == "FAFGAMEDATA": self.connection.writeToServer("PATCH_TO", destination, fileToUpdate, md5File, str(self.version)) else: self.connection.writeToServer( "MOD_PATCH_TO", destination, fileToUpdate, md5File, json.dumps(self.modversions)) else: self.connection.writeToServer("UPDATE", destination, fileToUpdate, md5File) self.waitUntilFilesAreUpdated() def waitForSimModPath(self): """ A simple loop that waits until the server has transmitted a sim mod path. """ self.lastData = time.time() self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) while self.modpath is None: if self.progress.wasCanceled(): raise UpdaterCancellation( "Operation aborted while waiting for sim mod path.") if self.result != self.RESULT_NONE: raise UpdaterFailure( "Operation failed while waiting for sim mod path.") if time.time() - self.lastData > self.TIMEOUT: raise UpdaterTimeout( "Operation timed out while waiting for sim mod path.") QtWidgets.QApplication.processEvents() def waitForFileList(self): """ A simple loop that waits until the server has transmitted a file list. """ self.lastData = time.time() self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) while len(self.filesToUpdate) == 0: if self.progress.wasCanceled(): raise UpdaterCancellation( "Operation aborted while waiting for file list.") if self.result != self.RESULT_NONE: raise UpdaterFailure( "Operation failed while waiting for file list.") if time.time() - self.lastData > self.TIMEOUT: raise UpdaterTimeout( "Operation timed out while waiting for file list.") QtWidgets.QApplication.processEvents() log("Files to update: [" + ', '.join(self.filesToUpdate) + "]") def waitUntilFilesAreUpdated(self): """ A simple loop that updates the progress bar while the server sends actual file data """ self.lastData = time.time() self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) while len(self.filesToUpdate) > 0: if self.progress.wasCanceled(): raise UpdaterCancellation( "Operation aborted while waiting for data.") if self.result != self.RESULT_NONE: raise UpdaterFailure( "Operation failed while waiting for data.") if time.time() - self.lastData > self.TIMEOUT: raise UpdaterTimeout( "Connection timed out while waiting for data.") QtWidgets.QApplication.processEvents() log("Updates applied successfully.") def prepareBinFAF(self): """ Creates all necessary files in the binFAF folder, which contains a modified copy of all that is in the standard bin folder of Forged Alliance """ self.progress.setLabelText("Preparing binFAF...") # now we check if we've got a binFAF folder FABindir = os.path.join(config.Settings.get("ForgedAlliance/app/path"), 'bin') FAFdir = util.BIN_DIR # Try to copy without overwriting, but fill in any missing files, otherwise it might miss some files to update root_src_dir = FABindir root_dst_dir = FAFdir for src_dir, _, files in os.walk(root_src_dir): dst_dir = src_dir.replace(root_src_dir, root_dst_dir) if not os.path.exists(dst_dir): os.mkdir(dst_dir) for file_ in files: src_file = os.path.join(src_dir, file_) dst_file = os.path.join(dst_dir, file_) if not os.path.exists(dst_file): shutil.copy(src_file, dst_dir) st = os.stat(dst_file) os.chmod( dst_file, st.st_mode | stat.S_IWRITE ) # make all files we were considering writable, because we may need to patch them def doUpdate(self): """ The core function that does most of the actual update work.""" try: if self.sim: self.connection.writeToServer("REQUEST_SIM_PATH", self.featured_mod) self.waitForSimModPath() if self.result == self.RESULT_SUCCESS: if modvault.downloadMod(self.modpath): self.connection.writeToServer("ADD_DOWNLOAD_SIM_MOD", self.featured_mod) else: # Prepare FAF directory & all necessary files self.prepareBinFAF() # Update the mod if it's requested if self.featured_mod == "faf" or self.featured_mod == "ladder1v1": # HACK - ladder1v1 "is" FAF. :-) self.updateFiles("bin", "FAF") self.updateFiles("gamedata", "FAFGAMEDATA") pass elif self.featured_mod: self.updateFiles("bin", "FAF") self.updateFiles("gamedata", "FAFGAMEDATA") self.updateFiles("bin", self.featured_mod) self.updateFiles("gamedata", self.featured_mod + "Gamedata") except UpdaterTimeout as e: log("TIMEOUT: {}".format(e)) self.result = self.RESULT_FAILURE except UpdaterCancellation as e: log("CANCELLED: {}".format(e)) self.result = self.RESULT_CANCEL except Exception as e: log("EXCEPTION: {}".format(e)) self.result = self.RESULT_FAILURE else: self.result = self.RESULT_SUCCESS finally: self.connection.disconnect() # Hide progress dialog if it's still showing. self.progress.close() # Integrated handlers for the various things that could go wrong if self.result == self.RESULT_CANCEL: pass # The user knows damn well what happened here. elif self.result == self.RESULT_PASS: QtWidgets.QMessageBox.information( QtWidgets.QApplication.activeWindow(), "Installation Required", "You can't play without a legal version of Forged Alliance.") elif self.result == self.RESULT_BUSY: QtWidgets.QMessageBox.information( QtWidgets.QApplication.activeWindow(), "Server Busy", "The Server is busy preparing new patch files.<br/>Try again later." ) elif self.result == self.RESULT_FAILURE: failureDialog() # If nothing terribly bad happened until now, # the operation is a success and/or the client can display what's up. return self.result def handleAction(self, bytecount, action, stream): """ Process server responses by interpreting its intent and then acting upon it """ log("handleAction(%s) - %d bytes" % (action, bytecount)) if action == "PATH_TO_SIM_MOD": path = stream.readQString() self.modpath = path self.result = self.RESULT_SUCCESS return elif action == "SIM_MOD_NOT_FOUND": log("Error: Unknown sim mod requested.") self.modpath = "" self.result = self.RESULT_FAILURE return elif action == "LIST_FILES_TO_UP": # Used to be an eval() here, this is a safe backwards-compatible fix listStr = str(stream.readQString()) self.filesToUpdate = ast.literal_eval(listStr) if self.filesToUpdate is None: self.filesToUpdate = [] return elif action == "UNKNOWN_APP": log("Error: Unknown app/mod requested.") self.result = self.RESULT_FAILURE return elif action == "THIS_PATCH_IS_IN_CREATION EXCEPTION": log("Error: Patch is in creation.") self.result = self.RESULT_BUSY return elif action == "VERSION_PATCH_NOT_FOUND": response = stream.readQString() log("Error: Patch version %s not found for %s." % (self.version, response)) self.connection.writeToServer("REQUEST_VERSION", self.destination, response, self.version) return elif action == "VERSION_MOD_PATCH_NOT_FOUND": response = stream.readQString() log("Error: Patch version %s not found for %s." % (str(self.modversions), response)) self.connection.writeToServer("REQUEST_MOD_VERSION", self.destination, response, json.dumps(self.modversions)) return elif action == "PATCH_NOT_FOUND": response = stream.readQString() log("Error: Patch not found for %s." % response) self.connection.writeToServer("REQUEST", self.destination, response) return elif action == "UP_TO_DATE": response = stream.readQString() log("file : " + response) log("%s is up to date." % response) self.filesToUpdate.remove(str(response)) return elif action == "ERROR_FILE": response = stream.readQString() log("ERROR: File not found on server : %s." % response) self.filesToUpdate.remove(str(response)) self.result = self.RESULT_FAILURE return elif action == "SEND_FILE_PATH": path = stream.readQString() fileToCopy = stream.readQString() url = stream.readQString() toFile = os.path.join(util.APPDATA_DIR, str(path), str(fileToCopy)) self.fetchFile(url, toFile) self.filesToUpdate.remove(str(fileToCopy)) self.updatedFiles.append(str(fileToCopy)) elif action == "SEND_FILE": path = stream.readQString() # HACK for feature/new-patcher path = util.LUA_DIR if path == "bin" else path fileToCopy = stream.readQString() size = stream.readInt() fileDatas = stream.readRawData(size) toFile = os.path.join(util.APPDATA_DIR, str(path), str(fileToCopy)) writeFile = QtCore.QFile(toFile) if writeFile.open(QtCore.QIODevice.WriteOnly): writeFile.write(fileDatas) writeFile.close() else: logger.warning( "%s is not writeable in in %s. Skipping." % (fileToCopy, path)) # This may or may not be desirable behavior log("%s is copied in %s." % (fileToCopy, path)) self.filesToUpdate.remove(str(fileToCopy)) self.updatedFiles.append(str(fileToCopy)) elif action == "SEND_PATCH_URL": destination = str(stream.readQString()) fileToUpdate = str(stream.readQString()) url = str(stream.readQString()) toFile = os.path.join(util.CACHE_DIR, "temp.patch") # if self.fetchFile(url, toFile): completePath = os.path.join(util.APPDATA_DIR, destination, fileToUpdate) self.applyPatch(completePath, toFile) log("%s/%s is patched." % (destination, fileToUpdate)) self.filesToUpdate.remove(str(fileToUpdate)) self.updatedFiles.append(str(fileToUpdate)) else: log("Failed to update file :'(") else: log("Unexpected server command received: " + action) self.result = self.RESULT_FAILURE def applyPatch(self, original, patch): toFile = os.path.join(util.CACHE_DIR, "patchedFile") # applying delta if sys.platform == 'win32': xdelta = os.path.join(fafpath.get_libdir(), "xdelta3.exe") else: xdelta = "xdelta3" subprocess.call([xdelta, '-d', '-f', '-s', original, patch, toFile], stdout=subprocess.PIPE) shutil.copy(toFile, original) os.remove(toFile) os.remove(patch) # Connection handler methods start here def atConnectionError(self, error): self.result = self.RESULT_FAILURE def atConnectionRead(self): self.lastData = time.time() # Keep resetting that timeout counter def atNewBlock(self, blockSize): if blockSize > 65536: self.progress.setLabelText("Downloading...") self.progress.setValue(0) self.progress.setMaximum(blockSize) else: self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) # Update our Gui at least once before proceeding # (we might be receiving a huge file and this is not the first time we get here) self.lastData = time.time() QtWidgets.QApplication.processEvents() def atBlockProgress(self, avail, blockSize): self.progress.setValue(avail) def atBlockComplete(self, blockSize, block): self.progress.setValue(blockSize) # Update our Gui at least once before proceeding (we might have to write a big file) self.lastData = time.time() QtWidgets.QApplication.processEvents() action = block.readQString() self.handleAction(blockSize, action, block) self.progress.setValue(0) self.progress.setMinimum(0) self.progress.setMaximum(0) self.progress.reset()
def loadSettings(self): self.mode = Settings.get(self._settings_key+'/mode', 'friends') self.checkBoxFriends.setCheckState(QtCore.Qt.Checked if self.mode == 'friends' else QtCore.Qt.Unchecked) self.parent.mode = self.mode
# Developer mode flag def developer(): return sys.executable.endswith("python.exe") from config import VERSION as VERSION_STRING import logging logger = logging.getLogger(__name__) LOGFILE_MAX_SIZE = 256 * 1024 # 256kb should be enough for anyone UNITS_PREVIEW_ROOT = "{}/faf/unitsDB/icons/big/".format( Settings.get('content/host')) import fafpath COMMON_DIR = fafpath.get_resdir() stylesheets = {} # map [qt obj] -> filename of stylesheet APPDATA_DIR = Settings.get('client/data_path') # This is used to store init_*.lua files LUA_DIR = os.path.join(APPDATA_DIR, "lua") # This contains the themes THEME_DIR = os.path.join(APPDATA_DIR, "themes") # This contains cached data downloaded while communicating with the lobby - at the moment, mostly map preview pngs.
def tech_support(self): QDesktopServices().openUrl(QUrl(Settings.get("SUPPORT_URL")))
from PyQt4 import QtCore, QtNetwork, QtGui import logging import json from config import Settings import struct FAF_SERVER_HOST = Settings.get('relay_server/host') FAF_SERVER_PORT = Settings.get('relay_server/port') class Packet(): def __init__(self, header=None , data=None, *values, **kwvalues): self._data = data self._values = kwvalues self._header = header def Pack(self): data = "" headerSize = len(str(self._header)) headerField = str(self._header).replace("\t","/t").replace("\n","/n") chunkSize = len(self._data) headerPackStr = "<i" + str(headerSize) + "si" data += struct.pack(headerPackStr, headerSize, headerField, chunkSize) for field in self._data :
def __init__(self, exc_info, *args, **kwargs): QtGui.QDialog.__init__(self, *args, **kwargs) exc_type, exc_value, traceback_object = exc_info dialog = self if kwargs.get('automatic'): automatic = True else: automatic = Settings.get('client/auto_bugreport', type=bool, default=True) self.trace = "".join(traceback.format_exception(exc_type, exc_value, traceback_object, 10)) if automatic: self.title = "Bug report" else: self.title = "Report from " + CRASH_REPORT_USER + u": " + str(exc_value) self.bugreport_target = BugReportTarget('client', 'https://github.com/FAForever/client', config.VERSION) self.bugreport = BugReport(self.title, target=self.bugreport_target, traceback=self.trace, automatic=automatic) dialog.setWindowTitle(self.title) description = u"" try: description += (u"\n**FAF Username:** " + CRASH_REPORT_USER) description += (u"\n**FAF Version:** " + VERSION_STRING) description += (u"\n**FAF Environment:** " + config.environment) description += (u"\n**FAF Directory:** " + APPDATA_DIR) description += (u"\n**FA Path:** " + str(util.settings.value("ForgedAlliance/app/path", None, type=str))) description += (u"\n**Home Directory:** " + PERSONAL_DIR) except StandardError: description += (u"\n**(Exception raised while writing debug vars)**") log = u"" try: log += (u"\n".join(readlines(LOG_FILE_FAF, False)[-128:])) except StandardError: log += (unicode(LOG_FILE_FAF)) log += (u"empty or not readable") self.bugreport.description = description self.bugreport.log = log if not automatic: self.box = QtGui.QTextEdit() self.box.setFont(QtGui.QFont("Lucida Console", 8)) self.box.append(description) dialog.layout().addWidget(self.box) dialog.setLayout(QtGui.QVBoxLayout()) label = QtGui.QLabel() label.setText( "An error has occurred in the FAF client. <br><br>You can report it by clicking the ticket button.") label.setWordWrap(True) dialog.layout().addWidget(label) label = QtGui.QLabel() label.setText("<b>This is what happened. If you have more to add please write in the field below.</b>") label.setWordWrap(False) dialog.layout().addWidget(label) self.sendButton = QtGui.QPushButton("\nReport error\n") self.sendButton.pressed.connect(self.post_report) dialog.layout().addWidget(self.sendButton) label = QtGui.QLabel() label.setText("<b></b><br/><i>(please note that the error may be fatal, proceed at your own risk)</i>") label.setWordWrap(False) dialog.layout().addWidget(label) self.buttons = QtGui.QDialogButtonBox() buttons = self.buttons buttons.addButton("Continue", QtGui.QDialogButtonBox.AcceptRole) buttons.addButton("Close FAF", QtGui.QDialogButtonBox.RejectRole) buttons.addButton("Help", QtGui.QDialogButtonBox.HelpRole) buttons.accepted.connect(dialog.accept) buttons.rejected.connect(dialog.reject) buttons.helpRequested.connect(self.tech_support) dialog.layout().addWidget(buttons) else: dialog.setLayout(QtGui.QVBoxLayout()) label = QtGui.QLabel() label.setText("An error has occurred in the FAF client. It has been automatically reported.") label.setWordWrap(True) dialog.layout().addWidget(label) self.post_report() self.sendButton = QtGui.QPushButton("\nOK\n") self.sendButton.pressed.connect(dialog.accept) dialog.layout().addWidget(self.sendButton)
def viewAliases(self): QtGui.QDesktopServices.openUrl( QUrl("{}?name={}".format(Settings.get("NAME_CHANGE_URL"), self.name)))
def _loadRelations(self): if self._key is not None: rel = Settings.get(self._key) self._relations = set(rel) if rel is not None else set() else: self._relations = set()
def _readloop(self): bs = self.blocksize if self.blocksize is not None else self._dfile.bytesAvailable() self.dest.write(self._dfile.read(bs)) self.cb_progress(self) def succeeded(self): return not self.error and not self.canceled def waitForCompletion(self): waitFlag = QtCore.QEventLoop.WaitForMoreEvents while self._running: QtWidgets.QApplication.processEvents(waitFlag) MAP_PREVIEW_ROOT = "{}/faf/vault/map_previews/small/".format(Settings.get('content/host')) class PreviewDownload(QtCore.QObject): done = QtCore.pyqtSignal(object, object) def __init__(self, nam, name, url, target_dir, delay_timer=None): QtCore.QObject.__init__(self) self.requests = set() self.name = name self._url = url self._nam = nam self._target_dir = target_dir self._delay_timer = delay_timer self._dl = None if delay_timer is None:
def loadSettings(self): self.mode = Settings.get(self._settings_key + '/mode', 'friends') self.checkBoxFriends.setCheckState(QtCore.Qt.Checked if self.mode == 'friends' else QtCore.Qt.Unchecked) self.parent.mode = self.mode
def linkAccount(self): QtGui.QDesktopServices.openUrl( QtCore.QUrl(Settings.get("STEAMLINK_URL")))
import util import logging from vault import luaparser import warnings import io import zipfile from config import Settings from downloadManager import FileDownload from vault.dialogs import VaultDownloadDialog, downloadVaultAsset logger = logging.getLogger(__name__) MODFOLDER = os.path.join(util.PERSONAL_DIR, "My Games", "Gas Powered Games", "Supreme Commander Forged Alliance", "Mods") MODVAULT_DOWNLOAD_ROOT = "{}/faf/vault/".format(Settings.get('content/host')) installedMods = [] # This is a global list that should be kept intact. # So it should be cleared using installedMods[:] = [] # mods selected by user, are not overwritten by temporary mods selected when joining game selectedMods = Settings.get('play/mods', default=[]) class ModInfo(object): def __init__(self, **kwargs): self.name = "Not filled in" self.version = 0 self.folder = "" self.__dict__.update(kwargs)
def forgotPassword(self): QtGui.QDesktopServices.openUrl( QtCore.QUrl(Settings.get("PASSWORD_RECOVERY_URL")))
# Initialize logging system import logging from PyQt4.QtNetwork import QNetworkAccessManager from enum import IntEnum from config import Settings from .player import Player logger = logging.getLogger(__name__) # logger.setLevel(logging.DEBUG) # Initialize all important globals LOBBY_HOST = Settings.get("lobby/host") LOBBY_PORT = Settings.get("lobby/port") LOCAL_REPLAY_PORT = Settings.get("lobby/relay/port") class ClientState(IntEnum): """ Various states the client can be in. """ SHUTDOWN = -666 # Going... DOWN! # Disconnected state # We enter this state if either: # - The user requested it # - We've reconnected too many times DISCONNECTED = -4
def viewAliases(self): QtGui.QDesktopServices.openUrl(QUrl("{}?name={}".format(Settings.get("NAME_CHANGE_URL"), self.name)))
from PyQt4 import QtCore, QtNetwork, QtGui import os import logging import util import fa import json import time from config import Settings INTERNET_REPLAY_SERVER_HOST = Settings.get('replay_server/host') INTERNET_REPLAY_SERVER_PORT = Settings.get('replay_server/port') from . import DEFAULT_LIVE_REPLAY from . import DEFAULT_RECORD_REPLAY class ReplayRecorder(QtCore.QObject): """ This is a simple class that takes all the FA replay data input from its inputSocket, writes it to a file, and relays it to an internet server via its relaySocket. """ __logger = logging.getLogger(__name__) def __init__(self, parent, local_socket, *args, **kwargs): QtCore.QObject.__init__(self, *args, **kwargs) self.parent = parent
def reportBug(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("TICKET_URL")))
def loadSettings(self): self.enabled = Settings.get('notifications/enabled', True, type=bool) self.popup_lifetime = Settings.get('notifications/popup_lifetime', 5, type=int) self.nsEnabled.setChecked(self.enabled) self.nsPopLifetime.setValue(self.popup_lifetime)
from PyQt4 import QtCore, QtGui, QtNetwork import functools import logging import config from config import Settings FAF_PROXY_HOST = Settings.get('proxy/host') FAF_PROXY_PORT = Settings.get('proxy/port') UNIT16 = 8 class proxies(QtCore.QObject): __logger = logging.getLogger(__name__) def __init__(self, parent=None): super(proxies, self).__init__(parent) self.client = parent self.proxies = {} self.proxiesDestination = {} port = 12000 errored = False for i in range(11) :
def renameAccount(self): QtGui.QDesktopServices.openUrl( QtCore.QUrl(Settings.get("NAME_CHANGE_URL")))
def linkAccount(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("STEAMLINK_URL")))
def reportBug(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("TICKET_URL")))
def renameAccount(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("NAME_CHANGE_URL")))
import stat import struct import shutil import urllib.request, urllib.error, urllib.parse import zipfile import tempfile import re # module imports import fa # local imports from config import Settings from vault.dialogs import downloadVaultAssetNoMsg logger = logging.getLogger(__name__) route = Settings.get('content/host') VAULT_PREVIEW_ROOT = "{}/faf/vault/map_previews/small/".format(route) VAULT_DOWNLOAD_ROOT = "{}/faf/vault/".format(route) VAULT_COUNTER_ROOT = "{}/faf/vault/map_vault/inc_downloads.php".format(route) from model.game import OFFICIAL_MAPS as maps __exist_maps = None def isBase(mapname): """ Returns true if mapname is the name of an official map """ return mapname in maps
def forgotPassword(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl(Settings.get("PASSWORD_RECOVERY_URL")))