示例#1
0
 def createNewGalaxy(self, tran, obj, x, y, galaxyName):
     log.message("Adding new galaxy '%s' to (%d, %d)" % (galaxyName, x, y))
     fh, galaxyFileName = tempfile.mkstemp(text=True)
     log.debug("Generating new galaxy to temporary file", galaxyFileName)
     strGalaxyID = 'Circle42P'
     GenerateGalaxy(strGalaxyID, os.fdopen(fh, "w+b"))
     log.debug("Creating new galaxy")
     newGalaxyID = self.createGalaxy(tran, obj)
     log.debug("Created new galaxy", newGalaxyID)
     newGalaxy = tran.db[newGalaxyID]
     log.debug("Loading new ", newGalaxyID)
     self.cmd(newGalaxy).loadFromXML(tran, newGalaxy, galaxyFileName,
                                     strGalaxyID, x, y, galaxyName)
     log.debug("Setup Enviroment", newGalaxyID)
     self.cmd(newGalaxy).setupEnvironment(tran, newGalaxy)
     log.debug("Sending Announcement Message", newGalaxyID)
     #self.cmd(newGalaxy).announceGalaxy(tran,newGalaxy)
     log.debug("Removing temp file", galaxyFileName)
     os.remove(galaxyFileName)
     # TODO: find you what's this code about
     #message = {
     #    "sender": 'Galaxy %s' % galaxyName,
     #    "senderID": obj.oid,
     #    "forum": "NEWS",
     #    "data": (obj.oid, MSG_GNC_GALAXY_GENERATOR, obj.oid, tran.db[OID_UNIVERSE].turn, (galaxyName, newGalaxy.description)),
     #    "topic": "EVENT",
     #}
     log.debug("Galaxy Restarting END")
示例#2
0
 def isUpdateAvailable(self):
     """Check if client version matches server version and update client
     if neccessary"""
     log.message("Checking for update...")
     if "oslauncher" in sys.modules:
         log.message("Application launched from Outer Space Launcher -- will not update")
         return False
     updateMode = gdata.config.client.updatemode or "normal"
     # quit if update is disabled
     if updateMode == 'never':
         return False
     # compare server and client versions
     log.message("Retrieving server version")
     try:
         self.serverVersion = client.cmdProxy.getVersion()
     except KeyError:
         # call is not supported on older server versions
         log.debug("getVersion call not supported")
         self.reportFailure(_("Server does not support update feature yet. Check for updates manually, please."))
         return None
     log.debug("Comparing server and client versions", self.serverVersion, ige.version.version)
     matches = True
     for i in ("major", "minor", "revision", "status"):
         if ige.version.version[i] != self.serverVersion[i]:
             matches = False
     if matches:
         log.message("Versions match, no need to update")
         return False
     log.message("Version do not match, update is needed")
     return True
示例#3
0
	def createNewGalaxy(self, tran, obj, x, y, galaxyName):
		log.message("Adding new galaxy '%s' to (%d, %d)" % (galaxyName, x, y))
		fh, galaxyFileName = tempfile.mkstemp(text = True)
		log.debug("Generating new galaxy to temporary file", galaxyFileName)
		strGalaxyID = tran.gameMngr.config.server.newgalaxytype
		GenerateGalaxy(strGalaxyID, os.fdopen(fh, "w+b"))
		log.debug("Creating new galaxy")
		newGalaxyID = self.createGalaxy(tran, obj)
		log.debug("Created new galaxy", newGalaxyID)
		newGalaxy = tran.db[newGalaxyID]
		log.debug("Loading new ", newGalaxyID)
		self.cmd(newGalaxy).loadFromXML(tran, newGalaxy, galaxyFileName, strGalaxyID, x, y, galaxyName)
		log.debug("Setup Enviroment", newGalaxyID)
		self.cmd(newGalaxy).setupEnvironment(tran, newGalaxy)
		log.debug("Sending Announcement Message", newGalaxyID)
		#self.cmd(newGalaxy).announceGalaxy(tran,newGalaxy)
		log.debug("Removing temp file", galaxyFileName)
		os.remove(galaxyFileName)
		# TODO: find you what's this code about
		#message = {
		#    "sender": 'Galaxy %s' % galaxyName,
		#    "senderID": obj.oid,
		#    "forum": "NEWS",
		#    "data": (obj.oid, MSG_GNC_GALAXY_GENERATOR, obj.oid, tran.db[OID_UNIVERSE].turn, (galaxyName, newGalaxy.description)),
		#    "topic": "EVENT",
                #}
		log.debug("Galaxy Restarting END")
示例#4
0
 def createNewGalaxy(self, tran, obj, x, y, galaxyName):
     galaxyType = tran.gameMngr.config.galaxytype
     if type(galaxyType) != str:
         # old configuration file
         log.debug("OLD configuration file detected, using server.newgalaxytype!")
         galaxyType = tran.gameMngr.config.server.newgalaxytype
         galaxyName = "Legacy Galaxy"
     assert galaxyType, "galaxytype must be defined in configuration file"
     print galaxyName
     log.message("Adding new galaxy '%s' with type '%s' to (%d, %d)" % (galaxyName, galaxyType, x, y))
     fh, galaxyFileName = tempfile.mkstemp(text = True)
     log.debug("Generating new galaxy to temporary file", galaxyFileName)
     GenerateGalaxy(galaxyType, os.fdopen(fh, "w+b"))
     log.debug("Creating new galaxy")
     newGalaxyID = self.createGalaxy(tran, obj)
     log.debug("Created new galaxy", newGalaxyID)
     newGalaxy = tran.db[newGalaxyID]
     log.debug("Loading new ", newGalaxyID)
     self.cmd(newGalaxy).loadFromXML(tran, newGalaxy, galaxyFileName, galaxyType, x, y, galaxyName)
     log.debug("Setup Enviroment", newGalaxyID)
     self.cmd(newGalaxy).setupEnvironment(tran, newGalaxy)
     log.debug("Sending Announcement Message", newGalaxyID)
     #self.cmd(newGalaxy).announceGalaxy(tran,newGalaxy)
     log.debug("Removing temp file", galaxyFileName)
     os.remove(galaxyFileName)
     # TODO: find you what's this code about
     #message = {
     #    "sender": 'Galaxy %s' % galaxyName,
     #    "senderID": obj.oid,
     #    "forum": "NEWS",
     #    "data": (obj.oid, MSG_GNC_GALAXY_GENERATOR, obj.oid, tran.db[OID_UNIVERSE].turn, (galaxyName, newGalaxy.description)),
     #    "topic": "EVENT",
             #}
     log.debug("Galaxy creation END")
示例#5
0
 def processDir(arg, dirname, names):
     log.message('Loading XML files from', dirname)
     names.sort()
     for filename in names:
         if os.path.splitext(filename)[1] == '.xml':
             log.message('Parsing XML file', filename)
             xml.sax.parse(os.path.join(dirname, filename), TechTreeContentHandler())
示例#6
0
    def _autoFinishOuterspace(self, tran, obj, galaxy):
        if tran.gameMngr.config.server.mode != "normal":
            # check autoend conditions, but only in normal mode
            # development mode does not end galaxies
            return
        for playerID in obj.players:
            player = tran.db[playerID]
            if galaxy.oid != player.galaxy:
                continue
            if player.type == Const.T_PIRPLAYER:
                piratePlayer = True
                activePlayerCount += 1
                continue
            if player.type != Const.T_PLAYER:
                continue
            selfName = player.name
            activePlayerCount += 1

        if activePlayerCount <= 1:
            log.message("AUTO FINISHING GALAXY", galaxy.oid)
            if activePlayerCount == 0:
                self.finishGalaxyAutomated(tran, obj, galaxy.oid, ["The galaxy was ended with no active players."])
            elif piratePlayer: #if the pirate is still alive, then he must be the winner.
                self.finishGalaxyAutomated(tran, obj, galaxy.oid, ["The galaxy was automatically ended with the Pirate as a winner!"])
            elif selfName: #if there is only one player, selfName must be themselves if it isn't null
                self.finishGalaxyAutomated(tran, obj, galaxy.oid, ["The galaxy was automatically ended with commander %s as the only remaining player." % selfName])
示例#7
0
    def restore(self, backupPath):
        """ Extracts data of the ai players, as well as the ais_list file.

		"""
        os.remove(os.path.join(self.configDir, "ais_list"))
        shutil.rmtree(os.path.join(self.configDir, "ai_data"))
        log.message("Restoring AI backup %s" % backupPath)
        tar = tarfile.open(backupPath, "r:bz2")
        tar.extractall()
        tar.close()
        self.lines = {}
        # parsing the file
        try:
            listfile = open(os.path.join(self.configDir, "ais_list"), "r")
            for row in listfile:
                line = row.strip().split(" ")
                if len(line) == 3:
                    self.lines.update({line[0]: tuple([line[1], line[2]])})
                elif len(line) == 4:
                    self.lines.update({line[0]: tuple([line[1], line[2], line[3]])})
                else:
                    continue
            listfile.close()
        except Exception, e:
            listfile = open(os.path.join(self.configDir, "ais_list"), "a")
            listfile.close()
示例#8
0
    def createNewSubscribedGalaxy(self, tran, obj, galaxyName, galaxyType, listOfPlayers):
        galGen = GalaxyGenerator.GalaxyGenerator()
        galaxyRadius = galGen.getGalaxyTemplate(galaxyType).radius
        posX, posY = self.cmd(obj).findSpotForGalaxy(tran, obj, galaxyRadius)
        log.message("Adding new galaxy '%s' to (%d, %d)" % (galaxyType, posX, posY))
        galaxyFileName = galGen.generateGalaxy(galaxyType)
        log.debug("Creating new galaxy")
        newGalaxyID = self.createGalaxy(tran, obj)
        log.debug("Created new galaxy", newGalaxyID)
        newGalaxy = tran.db[newGalaxyID]
        log.debug("Loading new ", newGalaxyID)
        self.cmd(newGalaxy).loadFromXML(tran, newGalaxy, galaxyFileName, galaxyType, posX, posY, galaxyName)

        log.debug("Setup Enviroment", newGalaxyID)
        self.cmd(newGalaxy).setupEnvironment(tran, newGalaxy)
        log.debug("Sending Announcement Message", newGalaxyID)
        #self.cmd(newGalaxy).announceGalaxy(tran,newGalaxy)
        log.debug("Removing temp file", galaxyFileName)
        os.remove(galaxyFileName)
        for playerLogin in listOfPlayers:
            tran.gameMngr.createNewSubscribedPlayer(playerLogin, newGalaxyID)
        if newGalaxy.scenario != Const.SCENARIO_SINGLE:
            # no point in announcing single scenario - it starts ticking right away
            self._sendCreationMessage(tran, obj, newGalaxy)
        log.debug("Galaxy creation END")
        return newGalaxyID
示例#9
0
 def enableTime(self, tran, obj, force=False):
     log.debug('IGalaxy', 'Checking for time...')
     if not force and not self._isEligibleEnableTime(tran, obj):
         return
     if obj.timeEnabled is None:
         self._firstEnableTime(tran, obj)
     # ok, enable time
     log.message('IGalaxy', 'Enabling time for', obj.oid)
     obj.timeEnabled = True
     self._trickleTimeToPlayers(tran, obj)
示例#10
0
 def enableTime(self, tran, obj, force = False):
     log.debug('IGalaxy', 'Checking for time...')
     if not force and not self._isEligibleEnableTime(tran, obj):
         return
     if obj.timeEnabled is None:
         self._firstEnableTime(tran, obj)
     # ok, enable time
     log.message('IGalaxy', 'Enabling time for', obj.oid)
     obj.timeEnabled = True
     self._trickleTimeToPlayers(tran, obj)
示例#11
0
def importFromPath(path):
    import sys
    oldpath = sys.path
    try:
        sys.path = [path]
        log.debug("Rules import - using path", sys.path)
        exec "from rules import *" in globals()
        log.message("Rules import succeeded")
    finally:
        sys.path = oldpath
示例#12
0
 def loadFromXML(self, tran, obj, file, galID, x, y, name):
     log.message('IGalaxy', 'Parsing XML file...')
     dom = parse(os.path.join('data', file))
     log.message('IGalaxy', 'XML file parsed.')
     assert dom.documentElement.tagName == 'universe'
     for node in dom.documentElement.childNodes:
         if node.nodeType == Node.ELEMENT_NODE and node.tagName == 'galaxy':
             if node.getAttribute('id') == galID:
                 self.loadDOMNode(tran, obj, node, x, y, name)
                 self.connectWormHoles(tran, obj)
                 return SUCC
     raise GameException('No such id %s in resource' % galID)
示例#13
0
 def __init__(self, configuration):
     self.loadConfigFile(configuration)
     # inititalization
     self.initializeSharedMngrs()
     # initialize games
     self.games = list()
     for section in self.config.sections():
         if not section.startswith("game"):
             continue
         config = self.config[section]
         log.message("INITIALIZING GAME", config.gameid)
         self.initializeGame(config)
示例#14
0
 def __init__(self, configuration):
     self.loadConfigFile(configuration)
     # inititalization
     self.initializeSharedMngrs()
     # initialize games
     self.games = list()
     for section in self.config.sections():
         if not section.startswith("game"):
             continue
         config = self.config[section]
         log.message("INITIALIZING GAME", config.gameid)
         self.initializeGame(config)
示例#15
0
	def loadFromXML(self, tran, obj, file, galID, x, y, name):
		log.message('IGalaxy', 'Parsing XML file...')
		dom = parse(os.path.join('data', file))
		log.message('IGalaxy', 'XML file parsed.')
		assert dom.documentElement.tagName == 'universe'
		for node in dom.documentElement.childNodes:
			if node.nodeType == Node.ELEMENT_NODE and node.tagName == 'galaxy':
				if node.getAttribute('id') == galID:
					self.loadDOMNode(tran, obj, node, x, y, name)
					self.connectWormHoles(tran, obj)
					return SUCC
		raise GameException('No such id %s in resource' % galID)
示例#16
0
 def performDownload(self, updateDirectory):
     """Download zip with new version"""
     log.debug('Downloading new version')
     self.setProgress('Preparing download...', 0, 1)
     # setup proxies
     proxies = {}
     if gdata.config.proxy.http != None:
         proxies['http'] = gdata.config.proxy.http
     log.debug('Using proxies', proxies)
     # get file
     try:
         # open URL
         opener = urllib.build_opener(urllib.ProxyHandler(proxies))
         # it unfortunately is not completely reliable
         for i in range(1, 5):
             try:
                 ifh = opener.open(self.url)
                 log.debug("Retrieving URL", ifh.geturl())
                 # download file
                 total = int(ifh.info()["content-length"])
                 basename = re.search(
                     '(?<=filename=).*',
                     ifh.info()["content-disposition"]).group(0)
                 break
             except KeyError:
                 pygame.time.wait(1)
         if not basename:
             log.message("URL is not a file")
             self.reportFailure(_("Error: URL does not point to a file."))
             return
         filename = os.path.join(updateDirectory, basename)
         log.debug("Downloading file %s of size %d" % (filename, total))
         ofh = open(filename, "wb")
         # download and report progress
         downloaded = 0
         while True:
             data = ifh.read(100000)
             if not data:
                 break
             ofh.write(data)
             downloaded += len(data)
             log.debug("Download progress", downloaded, total)
             self.setProgress("Downloading update...", downloaded, total)
         ifh.close()
         ofh.close()
         return filename
     except urllib.error.URLError as e:
         log.warning("Cannot download file")
         self.reportFailure(
             _("Cannot finish download: %(s)") % str(e.reason))
         return None
示例#17
0
def updateDatabaseUnsafe(clearDB=0, force=0):
    """Update database by fetching data from the server."""
    global lastUpdate, nonexistingObj, db
    # get real turn
    result = cmdProxy.getIntroInfo(Const.OID_UNIVERSE)
    if not db:
        db = IClientDB.IClientDB(result.cid, result.turn, options.configDir,
                                 cmdProxy.gameID)
    if clearDB:
        db.clear()
    db.turn = result.turn
    #
    if db.turn <= lastUpdate and not force:
        return
    log.message('IClient', 'Updating...')
    lastUpdate = db.turn
    nonexistingObj.clear()
    current = 0
    max = 1
    # compute total objects to be fetched
    max += 6  # clear map, get messages, ...
    current += 1
    # delete selected objects
    # reset combatCounters
    for objID in db.keys():
        obj = db[objID]
        if hasattr(obj, "combatCounter"):
            obj.combatCounter = 0
        if not hasattr(obj, 'type'):
            del db[objID]
        elif obj.type == Const.T_FLEET:
            del db[objID]
        elif hasattr(obj, 'owner') and obj.owner == db.playerID \
            and objID != db.playerID:
            # delete player's objects
            del db[objID]
        else:
            if hasattr(obj, "scanPwr"): obj.scanPwr = 0
            if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
    # update player
    db[db.playerID] = get(db.playerID)
    player = db[db.playerID]
    # update from scanner's map
    scannerMap = cmdProxy.getScannerMap(db.playerID)
    for objID in scannerMap:
        db[objID] = scannerMap[objID]
    # update player's planets and fleets
    for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
        db[obj.oid] = obj
    # finished
    log.message('IClient', 'Update finished.')
示例#18
0
def updateDatabaseUnsafe(clearDB = 0, force = 0):
    """Update database by fetching data from the server."""
    global lastUpdate, nonexistingObj, db
    # get real turn
    result = cmdProxy.getIntroInfo(Const.OID_UNIVERSE)
    if not db:
        db = IClientDB.IClientDB(result.cid, result.turn, options.configDir, cmdProxy.gameID)
    if clearDB:
        db.clear()
    db.turn = result.turn
    #
    if db.turn <= lastUpdate and not force:
        return
    log.message('IClient', 'Updating...')
    lastUpdate = db.turn
    nonexistingObj.clear()
    current = 0
    max = 1
    # compute total objects to be fetched
    max += 6 # clear map, get messages, ...
    current += 1
    # delete selected objects
    # reset combatCounters
    for objID in db.keys():
        obj = db[objID]
        if hasattr(obj, "combatCounter"):
            obj.combatCounter = 0
        if not hasattr(obj, 'type'):
            del db[objID]
        elif obj.type in (Const.T_FLEET, Const.T_ASTEROID):
            del db[objID]
        elif hasattr(obj, 'owner') and obj.owner == db.playerID \
            and objID != db.playerID:
            # delete player's objects
            del db[objID]
        else:
            if hasattr(obj, "scanPwr"): obj.scanPwr = 0
            if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
    # update player
    db[db.playerID] = get(db.playerID)
    player = db[db.playerID]
    # update from scanner's map
    scannerMap = cmdProxy.getScannerMap(db.playerID)
    for objID in scannerMap:
        db[objID] = scannerMap[objID]
    # update player's planets and fleets
    for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
        db[obj.oid] = obj
    # finished
    log.message('IClient', 'Update finished.')
示例#19
0
 def performDownload(self, updateDirectory):
     """Download zip with new version"""
     log.debug('Downloading new version')
     self.setProgress('Preparing download...', 0, 1)
     # setup proxies
     proxies = {}
     if gdata.config.proxy.http != None:
         proxies['http'] = gdata.config.proxy.http
     log.debug('Using proxies', proxies)
     # get file
     try:
         # open URL
         opener = urllib2.build_opener(urllib2.ProxyHandler(proxies))
         # it unfortunately is not completely reliable
         for i in xrange(1,5):
             try:
                 ifh = opener.open(self.url)
                 log.debug("Retrieving URL", ifh.geturl())
                 # download file
                 total = int(ifh.info()["content-length"])
                 basename = re.search('(?<=filename=).*', ifh.info()["content-disposition"]).group(0)
                 break
             except KeyError:
                 pygame.time.wait(1)
         if not basename:
             log.message("URL is not a file")
             self.reportFailure(_("Error: URL does not point to a file."))
             return
         filename = os.path.join(updateDirectory, basename)
         log.debug("Downloading file %s of size %d" % (filename, total) )
         ofh = open(filename, "wb")
         # download and report progress
         downloaded = 0
         while True:
             data = ifh.read(100000)
             if not data:
                 break
             ofh.write(data)
             downloaded += len(data)
             log.debug("Download progress", downloaded, total)
             self.setProgress("Downloading update...", downloaded, total)
         ifh.close()
         ofh.close()
         return filename
     except urllib2.URLError, e:
         log.warning("Cannot download file")
         self.reportFailure(_("Cannot finish download: %(s)") % str(e.reason))
         return None
示例#20
0
def initRules(path):
    log.message("Using ruleset", path)
    # import rules
    import sys
    try:
        importFromPath(path)
    except ImportError:
        path = os.path.join("res/rules", os.path.basename(path))
        importFromPath(path)
    # import technologies
    import Techs
    global techs, Tech
    techs, Tech = Techs.initTechnologies(path)
    global rulesetName, rulesetPath
    rulesetName = os.path.basename(path)
    rulesetPath = path
示例#21
0
    def restore(self, backupPath):
        """ Extracts data of the ai players, as well as the ais_list file.

        """
        os.remove(os.path.join(self.configDir, self.listname))
        shutil.rmtree(os.path.join(self.configDir, 'ai_data', self.gameName))
        log.message('Restoring AI backup {0}'.format(backupPath))
        tar = tarfile.open(backupPath, 'r:bz2')
        tar.extractall()
        tar.close()
        self.records = []
        # parsing the file
        try:
            self.records = json.load(open(os.path.join(self.configDir, self.listname), "r"), object_hook=aiRecordDecoder)
        except Exception, e:
            listfile = open(os.path.join(self.configDir, self.listname), "a")
            listfile.close()
示例#22
0
 def setUpdateAction(self):
     # check if update URL exists
     action, self.url = self.serverVersion["clientURLs"].get(sys.platform, self.serverVersion["clientURLs"]["*"])
     version = "%(major)s.%(minor)s.%(revision)s%(status)s" % self.serverVersion
     text = [
         _("Server requires client version %s. It is recommended to update your client.") % version,
     ]
     if action == "browser":
         # open webbrowser with given url
         text.append(_("Do you want to display download page?"))
         self.win.vConfirm.action = "onLaunchBrowser"
     elif action == "execute":
         # download and run binary installer
         text.append(_("Do you want to download and install new version?"))
         self.win.vConfirm.action = "onDownloadAndInstall"
     else:
         log.message("Unsupported update action", action)
         self.onCancel(None, None, _("Unsupported update type."))
     self.win.vText.text = text
示例#23
0
 def enableTime(self, tran, obj, force=0, deleteSP=0, enable=1):
     log.debug('IGalaxy', 'Checking for time...')
     if not force:
         if obj.timeEnabled:
             return
         canRun = 0
         # there must be at least 1/2 positions already assigned
         #if len(obj.startingPos) <= obj.numOfStartPos / 2 and obj.creationTime < time.time() - 2 * 24 * 3600:
         #   log.debug("Half galaxy populated", len(obj.startingPos), obj.numOfStartPos)
         #   canRun = 1
         # at least two days must pass from creation
         if not obj.startingPos:
             log.debug("All positions taken, starting galaxy")
             canRun = 1
         if obj.creationTime < time.time() - 2 * 24 * 3600:
             log.debug("Two days passed", obj.creationTime,
                       time.time() - 2 * 24 * 3600)
             canRun = 1
         if not canRun:
             return 0
     # ok, enable time
     log.message('IGalaxy', 'Enabling time for', obj.oid)
     obj.timeEnabled = enable
     # close galaxy
     if deleteSP:
         obj.startingPos = []
     # load new galaxy
     # TODO
     # enable time for players
     for systemID in obj.systems:
         system = tran.db[systemID]
         for planetID in system.planets:
             planet = tran.db[planetID]
             if planet.owner != OID_NONE:
                 player = tran.db[planet.owner]
                 if player.timeEnabled != enable:
                     player.timeEnabled = enable
                     player.lastLogin = time.time()
                     if enable:
                         Utils.sendMessage(tran, player, MSG_ENABLED_TIME,
                                           player.oid, None)
示例#24
0
 def onDownloadAndInstall(self, widget, action, data):
     """Download and run installer of the new version"""
     self.setProgress('Preparing download...', 0, 1)
     # setup proxies
     proxies = {}
     if gdata.config.proxy.http != None:
         proxies['http'] = gdata.config.proxy.http
     log.debug('Using proxies', proxies)
     # get file
     try:
         # open URL
         opener = urllib2.build_opener(urllib2.ProxyHandler(proxies))
         ifh = opener.open(self.url)
         log.debug("Retrieving URL", ifh.geturl())
         # download file
         total = int(ifh.info()["Content-Length"])
         basename = os.path.basename(ifh.geturl())
         if not basename:
             log.message("URL is not a file")
             self.reportFailure(_("Error: URL does not point to a file."))
             return
         filename = os.path.join(self.options.configDir, basename)
         log.debug("Downloading file %s of size %d" % (filename, total) )
         ofh = open(filename, "wb")
         # download and report progress
         downloaded = 0
         while True:
             data = ifh.read(100000)
             if not data:
                 break
             ofh.write(data)
             downloaded += len(data)
             log.debug("Download progress", downloaded, total)
             self.setProgress("Downloading update...", downloaded, total)
         ifh.close()
         ofh.close()
     except urllib2.URLError, e:
         log.warning("Cannot download file")
         self.reportFailure(_("Cannot finish download: %(s)") % str(e.reason))
         return
示例#25
0
	def enableTime(self, tran, obj, force = 0, deleteSP = 0, enable = 1):
		log.debug('IGalaxy', 'Checking for time...')
		if not force:
			if obj.timeEnabled:
				return
			canRun = 0
			# there must be at least 1/2 positions already assigned
			#if len(obj.startingPos) <= obj.numOfStartPos / 2 and obj.creationTime < time.time() - 2 * 24 * 3600:
			#   log.debug("Half galaxy populated", len(obj.startingPos), obj.numOfStartPos)
			#   canRun = 1
			# at least two days must pass from creation
			if not obj.startingPos:
				log.debug("All positions taken, starting galaxy")
				canRun = 1
			if obj.creationTime < time.time() - 2 * 24 * 3600:
				log.debug("Two days passed", obj.creationTime, time.time() - 2 * 24 * 3600)
				canRun = 1
			if not canRun:
				return 0
		# ok, enable time
		log.message('IGalaxy', 'Enabling time for', obj.oid)
		obj.timeEnabled = enable
		# close galaxy
		if deleteSP:
			obj.startingPos = []
		# load new galaxy
		# TODO
		# enable time for players
		for systemID in obj.systems:
			system = tran.db[systemID]
			for planetID in system.planets:
				planet = tran.db[planetID]
				if planet.owner != OID_NONE:
					player = tran.db[planet.owner]
					if player.timeEnabled != enable:
						player.timeEnabled = enable
						player.lastLogin = time.time()
						if enable:
							Utils.sendMessage(tran, player, MSG_ENABLED_TIME, player.oid, None)
示例#26
0
 def initializeGame(self, config):
     """Initialize game according to configuration file fragment"""
     gameID = config.gameid
     # make sure we have required keys defined
     assert config.galaxytype, "%s.galaxytype MUST be defined" % gameID
     assert config.name, "%s.name MUST be defined" % gameID
     # initialize database and objects
     gameDB = Database(self.config.server.dbdir, "%s_game" % gameID, cache = 15000)
     msgDB = DatabaseString(self.config.server.dbdir, "%s_msgs" % gameID, cache = 1000)
     msgMngr = MsgMngr(msgDB)
     gameMngr = GameMngr(gameID, config, self.clientMngr, msgMngr, gameDB, self.config.server.datadir, config.name)
     # reset game if Universe does not exist
     if not gameDB.has_key(OID_UNIVERSE):
         log.message('Resetting game \'%s\'...' % gameID)
         gameMngr.reset()
     # normal operations
     gameMngr.init()
     if self.config.server.upgradegames:
         gameMngr.upgrade()
     msgMngr.upgrade()
     gameMngr.start()
     # keep reference to this game
     self.games.append(gameMngr)
示例#27
0
 def createNewSubscribedGalaxy(self, tran, obj, x, y, galaxyName, galaxyType, listOfPlayers):
     log.message("Adding new galaxy '%s' to (%d, %d)" % (galaxyName, x, y))
     fileHandle, galaxyFileName = tempfile.mkstemp(text = True)
     log.debug("Generating new galaxy to temporary file", galaxyFileName)
     galGen = GalaxyGenerator.GalaxyGenerator()
     galGen.generateGalaxy(galaxyType, os.fdopen(fileHandle, "w+b"))
     log.debug("Creating new galaxy")
     newGalaxyID = self.createGalaxy(tran, obj)
     log.debug("Created new galaxy", newGalaxyID)
     newGalaxy = tran.db[newGalaxyID]
     log.debug("Loading new ", newGalaxyID)
     self.cmd(newGalaxy).loadFromXML(tran, newGalaxy, galaxyFileName, galaxyType, x, y, galaxyName)
     log.debug("Running scripts specific to booked galaxies", newGalaxyID)
     self.cmd(newGalaxy).bookedInit(tran, newGalaxy)
     log.debug("Setup Enviroment", newGalaxyID)
     self.cmd(newGalaxy).setupEnvironment(tran, newGalaxy)
     log.debug("Sending Announcement Message", newGalaxyID)
     #self.cmd(newGalaxy).announceGalaxy(tran,newGalaxy)
     log.debug("Removing temp file", galaxyFileName)
     os.remove(galaxyFileName)
     for playerInfo in listOfPlayers:
         tran.gameMngr.createNewSubscribedPlayer(playerInfo, newGalaxyID)
     log.debug("Galaxy creation END")
示例#28
0
 def initializeGame(self, config):
     """Initialize game according to configuration file fragment"""
     gameID = config.gameid
     # make sure we have required keys defined
     assert config.galaxytype, "%s.galaxytype MUST be defined" % gameID
     assert config.name, "%s.name MUST be defined" % gameID
     # initialize database and objects
     gameDB = Database(self.config.server.dbdir, "%s_game" % gameID, cache = 15000)
     msgDB = DatabaseString(self.config.server.dbdir, "%s_msgs" % gameID, cache = 1000)
     msgMngr = MsgMngr(msgDB)
     gameMngr = GameMngr(gameID, config, self.clientMngr, msgMngr, gameDB, self.config.server.datadir, config.name)
     # reset game if Universe does not exist
     if not gameDB.has_key(OID_UNIVERSE):
         log.message('Resetting game \'%s\'...' % gameID)
         gameMngr.reset()
     # normal operations
     gameMngr.init()
     if self.config.server.upgradegames:
         gameMngr.upgrade()
     msgMngr.upgrade()
     gameMngr.start()
     # keep reference to this game
     self.games.append(gameMngr)
示例#29
0
文件: Techs.py 项目: Lukc/ospace-lukc
	def processDir(arg, dirname, names):
		if dirname.find(".svn") >= 0:
			log.message("Skipping directory", dirname)
			return
		log.message('Loading XML files from', dirname)
		names.sort()
		for filename in names:
			if os.path.splitext(filename)[1] == '.xml':
				log.message('Parsing XML file', filename)
				xml.sax.parse(os.path.join(dirname, filename), TechTreeContentHandler())
示例#30
0
	def processDir(arg, dirname, names):
		if dirname.find(".svn") >= 0:
			log.message("Skipping directory", dirname)
			return
		log.message('Loading XML files from', dirname)
		names.sort()
		for filename in names:
			if os.path.splitext(filename)[1] == '.xml':
				log.message('Parsing XML file', filename)
				contentHandler = TechTreeContentHandler()
				contentHandler.setGlobals(techs, Tech)
				xml.sax.parse(os.path.join(dirname, filename), contentHandler)
示例#31
0
 def isUpdateAvailable(self):
     """Check if client version matches server version and update client
     if neccessary"""
     log.message("Checking for update...")
     updateMode = gdata.config.client.updatemode or "normal"
     # quit if update is disabled
     if updateMode == 'never':
         return False
     # compare server and client versions
     log.message("Retrieving server version")
     self.serverVersion = client.cmdProxy.getVersion()
     log.debug("Comparing server and client versions", self.serverVersion, clientVersion)
     matches = True
     for i in ("major", "minor", "revision", "status"):
         if clientVersion[i] != self.serverVersion[i]:
             matches = False
     if matches:
         log.message("Versions match, no need to update")
         return False
     log.message("Version do not match, update is needed")
     return True
示例#32
0
def main():
    log.message("Starting IGE - Outer Space Messager Client version",
                Ver.versionString)
    log.debug("sys.path =", sys.path)
    log.debug("os.name =", os.name)

    # create required directories
    if not os.path.exists('var'):
        os.mkdir('var')

# parse configuration
    gdata.config = Config('var/osci.ini')

    # default configuration
    if gdata.config.game.server == None:
        gdata.config.game.server = 'www.ospace.net:9080'

# prepare internationalization
    if gdata.config.client.language == None:
        gdata.config.client.language = 'en'

    language = gdata.config.client.language

    import gettext
    try:
        tran = gettext.translation('OSPACE', 'res', languages=[language])
    except IOError:
        log.warning('OSCI', 'Cannot find catalog for', language)
        log.message('OSCI', 'Installing null translations')
        tran = gettext.NullTranslations()

    tran.install(unicode=1)
    log.message('OSCI', 'Translations installed for %s languaage' % language)

    # client
    from igeclient.IClient import IClientException

    client.initialize(gdata.config.game.server, handler)

    app = App(False)
    app.MainLoop()

    # write configuration
    log.debug("Saving configuration.")
    gdata.config.save('var/osci.ini')

    # logout
    client.logout()

    log.debug("Shut down")
示例#33
0
文件: main.py 项目: Lukc/ospace-lukc
def main():
	log.message("Starting IGE - Outer Space Messager Client version", Ver.versionString)
	log.debug("sys.path =", sys.path)
	log.debug("os.name =", os.name)

    # create required directories
	if not os.path.exists('var'):
		os.mkdir('var')

    # parse configuration
	gdata.config = Config('var/osci.ini')

    # default configuration
	if gdata.config.game.server == None:
		gdata.config.game.server = 'www.ospace.net:9080'

    # prepare internationalization
	if gdata.config.client.language == None:
		gdata.config.client.language = 'en'

	language = gdata.config.client.language

	import gettext
	try:
		tran = gettext.translation('OSPACE', 'res', languages = [language])
	except IOError:
		log.warning('OSCI', 'Cannot find catalog for', language)
		log.message('OSCI', 'Installing null translations')
		tran = gettext.NullTranslations()

	tran.install(unicode = 1)
	log.message('OSCI', 'Translations installed for %s languaage' % language)

	# client
	from igeclient.IClient import IClientException

	client.initialize(gdata.config.game.server, handler)

	app = App(False)
	app.MainLoop()

	# write configuration
	log.debug("Saving configuration.")
	gdata.config.save('var/osci.ini')

	# logout
	client.logout()

	log.debug("Shut down")
示例#34
0
def createRSAKeys():
    """Load or generate and save RSA keys"""
    global publicKey, privateKey
    if os.path.exists("var/private.pem"):
        log.message("Loading PRIVATE RSA key")
        privateKey = rsa.PrivateKey.load_pkcs1(open("var/private.pem", "rb").read())
    if os.path.exists("var/public.pem"):
        log.message("Loading PUBLIC RSA key")
        publicKey = rsa.PublicKey.load_pkcs1(open("var/public.pem", "rb").read())
    if privateKey and publicKey:
        return
    # no keys, let's generate them
    log.message("Generating RSA keys, please wait...")
    publicKey, privateKey = rsa.newkeys(2048)
    open("var/public.pem", "w").write(publicKey.save_pkcs1())
    open("var/private.pem", "w").write(privateKey.save_pkcs1())
示例#35
0
 def processFINAL2Phase(self, tran, obj, data):
     # distribute stats to contacts
     for playerID in obj.players:
         player = tran.db[playerID]
         for partyID in player.diplomacyRels:
             dipl = player.diplomacyRels[partyID]
             if dipl.contactType > CONTACT_NONE and tran.db.has_key(partyID):
                 dipl.stats = tran.db[partyID].stats
             else:
                 dipl.stats = None
     # imperator voting
     turn = tran.db[OID_UNIVERSE].turn
     if (turn + 2 * Rules.turnsPerDay) % Rules.voteForImpPeriod == 0:
         for galaxyID in obj.galaxies:
             galaxy = tran.db[galaxyID]
             if not galaxy.timeEnabled:
                 # skip this galaxy
                 continue
             message = {
                 "sender": "GNC",
                 "senderID": galaxyID,
                 "forum": "NEWS",
                 "data": (galaxyID, MSG_GNC_VOTING_COMING, galaxyID, turn, None),
                 "topic": "EVENT",
             }
             self.cmd(galaxy).sendMsg(tran, galaxy, message)
     if turn % Rules.voteForImpPeriod == 0:
         # voting
         # process each galaxy
         for galaxyID in obj.galaxies:
             log.debug("Voting for galaxy", galaxyID)
             galaxy = tran.db[galaxyID]
             if not galaxy.timeEnabled:
                 # skip this galaxy
                 continue
             # compute votes
             activePlayerCount = 0
             piratePlayer = False
             selfName = None
             sum = 0
             votes = {}
             votesID = {}
             voters = {}
             for playerID in obj.players:
                 player = tran.db[playerID]
                 if galaxyID not in player.galaxies:
                     log.debug("Skipping player", playerID, " - not in this galaxy")
                     continue
                 if player.type == T_PIRPLAYER:
                     log.debug("Skipping player", playerID, " - he/she is a pirate")
                     piratePlayer = True
                     activePlayerCount += 1
                     continue
                 if player.type != T_PLAYER:
                     log.debug("Skipping player", playerID, " - it's not a regular player")
                     # skip non-regular players
                     continue
                 selfName = player.name
                 # add to sum
                 log.debug(playerID, "votes for", player.voteFor, "with votes", player.stats.slots)
                 activePlayerCount += 1
                 sum += player.stats.slots
                 if player.voteFor == OID_NONE:
                     voteFor = None
                 else:
                     tmpPlayer = tran.db.get(player.voteFor, None)
                     if not tmpPlayer or tmpPlayer.type != T_PLAYER:
                         # reset vote
                         player.voteFor = OID_NONE
                         voteFor = None
                     else:
                         voteFor = tmpPlayer.name
                 # count votes
                 votes[voteFor] = votes.get(voteFor, 0) + player.stats.slots
                 votesID[player.voteFor] = votesID.get(player.voteFor, 0) + player.stats.slots
                 if voteFor in voters:
                     voters[voteFor].append(player.name)
                 else:
                     voters[voteFor] = [player.name]
             # check winner
             nominated = votesID.keys()
             nominated.sort(lambda a, b: cmp(votesID[b], votesID[a]))
             winnerID = OID_NONE
             # remove OID_NONE from the list
             if OID_NONE in nominated:
                 nominated.remove(OID_NONE)
             # check winner
             if nominated and float(votesID[nominated[0]]) / sum >= Rules.ratioNeededForImp:
                 # we have the imperator!
                 imperator = tran.db[nominated[0]]
                 # 2 imperator, 3+ winner
                 imperator.imperator = max(2, imperator.imperator + 1)
                 if galaxy.imperator != OID_NONE and galaxy.imperator != imperator.oid:
                     tran.db[galaxy.imperator].imperator = 0
                 galaxy.imperator = imperator.oid
                 # send message
                 message = {
                     "sender": "GNC",
                     "senderID": galaxyID,
                     "forum": "NEWS",
                     "data": (galaxyID, MSG_GNC_VOTING_IMPERATOR, galaxyID, turn, (imperator.name, (votes,voters))),
                     "topic": "EVENT",
                 }
                 self.cmd(galaxy).sendMsg(tran, galaxy, message)
             elif len(nominated) >= 1:
                 # we have the leader!
                 leader = tran.db[nominated[0]]
                 leader.imperator = 1
                 if galaxy.imperator != OID_NONE and galaxy.imperator != leader.oid:
                     tran.db[galaxy.imperator].imperator = 0
                 galaxy.imperator = leader.oid
                 # send message
                 message = {
                     "sender": "GNC",
                     "senderID": galaxyID,
                     "forum": "NEWS",
                     "data": (galaxyID, MSG_GNC_VOTING_LEADER, galaxyID, turn, (leader.name, (votes,voters))),
                     "topic": "EVENT",
                 }
                 self.cmd(galaxy).sendMsg(tran, galaxy, message)
             else:
                 # nobody wins
                 galaxy.imperator = OID_NONE
                 message = {
                     "sender": "GNC",
                     "senderID": galaxyID,
                     "forum": "NEWS",
                     "data": (galaxyID, MSG_GNC_VOTING_NOWINNER, galaxyID, turn, ((votes,voters),)),
                     "topic": "EVENT",
                 }
                 self.cmd(galaxy).sendMsg(tran, galaxy, message)
             # check one player win conditions, but only in normal mode (not development)
             if activePlayerCount <= 1 and tran.gameMngr.config.server.mode == "normal":
                 log.message("AUTO RESTARTING GALAXY", galaxyID)
                 if activePlayerCount == 0:
                     self.restartGalaxy2(tran, obj, galaxyID, ["The galaxy was ended with no active players."])
                 elif piratePlayer: #if the pirate is still alive, then he must be the winner.
                     self.restartGalaxy2(tran, obj, galaxyID, ["The galaxy was automatically ended with the Pirate as winner!"])
                 elif selfName: #if there is only one player, selfName must be themselves if it isn't null
                     self.restartGalaxy2(tran, obj, galaxyID, ["The galaxy was automatically ended with commander %s as the only remaining player." % selfName])
     # collect mailboxes
     used = [self.cmd(obj).getMailboxName(tran, obj)]
     for galaxyID in obj.galaxies:
         tmpObj = tran.db[galaxyID]
         used.append(self.cmd(tmpObj).getMailboxName(tran, tmpObj))
     for playerID in obj.players:
         tmpObj = tran.db[playerID]
         used.append(self.cmd(tmpObj).getMailboxName(tran, tmpObj))
     # trash unused mailboxes
     tran.gameMngr.msgMngr.trashUnusedMailboxes(used)
     return obj.galaxies
示例#36
0
def saveDB():
    if db:
        log.message('OSClient', 'Saving database')
        db.save()
示例#37
0
    def _save():
    # shut down game
        try:
            if game:
                log.message('Shutting down game...')
                game.shutdown()

            if msgMngr:
                log.message('Shutting down message manager...')
                msgMngr.shutdown()

            if clientMngr:
                log.message('Shutting down client manager...')
                clientMngr.shutdown()

            if issueMngr:
                log.message('Shutting down issue manager...')
                issueMngr.shutdown()

            if bookingMngr:
                log.message('Shutting down booking manager...')
                bookingMngr.shutdown()
        except:
            log.exception("Shutdown of the server failed")

        config.save()
        log.message('Shutted down')
        log.message("Cleaning up...")
示例#38
0
        optRestore = arg
    elif opt == "--config":
        optConfig = os.path.abspath(arg)
    elif opt == "--workingdir":
        optWorkingDir = arg

# change workding directory (if required)
if optWorkingDir:
    os.chdir(optWorkingDir)

# legacy logger
from ige import log
log.setMessageLog('var/logs/messages.log')
log.setErrorLog('var/logs/errors.log')

log.message("Working directory", os.getcwd())

# read configuration
from ige.Config import Config
log.message("Configuration file", optConfig)
config = Config(optConfig)

# record my pid
pidFd = os.open("var/server.pid", os.O_CREAT | os.O_EXCL | os.O_WRONLY)
os.write(pidFd, str(os.getpid()))
# TODO: check if server.pid points to the running process

game = None
msgMngr = None
clientMngr = None
issueMngr = None
示例#39
0
def updateDatabaseUnsafe(clearDB=0, force=0):
    """Update database by fetching data from the server."""
    global lastUpdate, nonexistingObj, db
    # get real turn
    result = cmdProxy.getIntroInfo(OID_UNIVERSE)
    if not db:
        db = IClientDB.IClientDB(result.cid, result.turn)
    if clearDB:
        db.clear()
    db.turn = result.turn
    #
    if db.turn <= lastUpdate and not force:
        return
    log.message('IClient', 'Updating...')
    lastUpdate = db.turn
    nonexistingObj.clear()
    # start updating...
    messageIgnore(SMESSAGE_NEWTURN)
    messageIgnore(SMESSAGE_NEWMESSAGE)
    callbackObj.onUpdateStarting()
    current = 0
    max = 1
    # compute total objects to be fetched
    max += 6  # clear map, get messages, ...
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Deleting obsolete data..."))
    # delete selected objects
    # reset combatCounters
    for objID in db.keys():
        obj = db[objID]
        if hasattr(obj, "combatCounter"):
            obj.combatCounter = 0
        if not hasattr(obj, 'type'):
            del db[objID]
        elif obj.type in (T_FLEET, T_ASTEROID):
            del db[objID]
        elif hasattr(obj, 'owner') and obj.owner == db.playerID \
         and objID != db.playerID:
            # delete player's objects
            del db[objID]
        else:
            if hasattr(obj, "scanPwr"): obj.scanPwr = 0
            if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
    # update player
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading player data..."))
    db[db.playerID] = get(db.playerID)
    player = db[db.playerID]
    # update from scanner's map
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Updating scanner..."))
    map = cmdProxy.getScannerMap(db.playerID)
    for objID in map:
        db[objID] = map[objID]
    # update player's planets and fleets
    current += 1
    callbackObj.onUpdateProgress(current, max,
                                 _("Downloading planets and fleets data..."))
    for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
        db[obj.oid] = obj
    #~ # compute system's positions
    #~ current += 1
    #~ callbackObj.onUpdateProgress(current, max, _("Updating astronomical coordinates..."))
    #~ systems = {}
    #~ for objID in db.keys():
    #~ obj = db[objID]
    #~ if obj.type == T_SYSTEM or obj.type == T_PLANET:
    #~ if obj.type == T_SYSTEM:
    #~ galaxy = get(obj.compOf)
    #~ system = obj
    #~ else:
    #~ if obj.compOf in systems:
    #~ system = systems[obj.compOf]
    #~ else:
    #~ system = get(obj.compOf, canBePublic = 0)
    #~ systems[obj.compOf] = system
    #~ if hasattr(system, "compOf"):
    #~ galaxy = get(system.compOf)
    #~ else:
    #~ continue
    #~ angle = system.sAngle / 1000.0 + (db.turn / Rules.rotationMod) * system.dAngle / 1000.0
    #~ obj.x = galaxy.x + system.dist * math.cos(angle) / 1000.0
    #~ obj.y = galaxy.y + system.dist * math.sin(angle) / 1000.0
    #~ del systems
    # TODO: try to load allies's info
    # get messages from server
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading messages..."))
    getMessages()
    # clean maps on server
    current += 1
    callbackObj.onUpdateProgress(current, max,
                                 _("Clearing data on the server..."))
    try:
        cmdProxy.setResolution(db.playerID, gdata.scrnSize[0],
                               gdata.scrnSize[1])
    except:
        log.debug('Server does not yet support resolution tracking')
    # TODO not needed - delete cmdProxy.clearScannerMap(db.playerID)
    # finished
    log.message('IClient', 'Update finished.')
    callbackObj.onUpdateFinished()
    messageEnable(SMESSAGE_NEWTURN)
    messageEnable(SMESSAGE_NEWMESSAGE)
示例#40
0
def init(configDir):
    global Tech, techs

    ## check, if anything has been changed

    def chsumDir(chsum, dirname, names):
        names.sort()
        for filename in names:
            if os.path.splitext(filename)[1] in ('.xml', '.py'):
                log.debug('Checking file', filename)
                fh = open(os.path.join(dirname, filename), 'rb')
                chsum.update(fh.read())
                fh.close()

    # compute checksum
    moduleFile = sys.modules['ige.ospace.Rules'].__file__
    forceLoad = 0

    # regular module
    moduleDirectory = os.path.dirname(moduleFile)
    chsum = hashlib.sha1()
    os.walk(moduleDirectory, chsumDir, chsum)

    # read old checksum
    try:
        fh = open(os.path.join(configDir, 'checksum'), 'rb')
        oldChsum = fh.read()
        fh.close()
    except IOError:
        oldChsum = ''

    # compare
    if forceLoad or chsum.hexdigest() == oldChsum:
        # load old definitions
        log.message('Loading stored specifications from', configDir)
        techs = pickle.load(open(os.path.join(configDir, 'techs.spf'), 'rb'))
        Tech = pickle.load(open(os.path.join(configDir, 'Tech.spf'), 'rb'))

        log.message("There is %d technologies" % len(techs))

        # clean up 'type' in lists
        for key in attrs.keys():
            if type(attrs[key]) == list and len(attrs[key]) == 1:
                log.debug("Cleaning up " + key)
                attrs[key] = []

    else:
        # create new ones
        ## load technologies definitions

        def processDir(arg, dirname, names):
            log.message('Loading XML files from', dirname)
            names.sort()
            for filename in names:
                if os.path.splitext(filename)[1] == '.xml':
                    log.message('Parsing XML file', filename)
                    xml.sax.parse(os.path.join(dirname, filename),
                                  TechTreeContentHandler())

        # collect xml files
        os.walk(moduleDirectory, processDir, None)

        # clean up 'type' in lists
        for key in attrs.keys():
            if type(attrs[key]) == list and len(attrs[key]) == 1:
                log.debug("Cleaning up " + key)
                attrs[key] = []
            elif type(attrs[key]) == dict and len(attrs[key]) == 1:
                log.debug("Cleaning up " + key)
                attrs[key] = {}

        # link tech tree using researchRequires fields
        # construct researchEnables fields
        log.message('Converting symbolic fields...')
        for techID in techs.keys():
            tech = techs[techID]
            # convert symbolic names to numbers
            techIDs = []
            for techSymName in tech.researchRequires:
                symName, improvement = techSymName.split('-')
                techIDs.append((getattr(Tech, symName), int(improvement)))
            tech.researchRequires = techIDs
            techIDs = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
            for techSymName in tech.researchEnables:
                improvement, symName = techSymName.split('-')
                techIDs[int(improvement)].append(getattr(Tech, symName))
            tech.researchEnables = techIDs
            techIDs = []
            for techSymName in tech.researchDisables:
                techIDs.append(getattr(Tech, techSymName))
            tech.researchDisables = techIDs
            techIDs = []
            if tech.unpackStruct:
                tech.unpackStruct = getattr(Tech, tech.unpackStruct)
            else:
                tech.unpackStruct = 0

            # strat. resources
            # this has to be here to prevent import deadlock in Rules
            from ige.ospace.Rules import stratResAmountBig
            from ige.ospace.Rules import stratResAmountSmall

            stratRes = []
            for sr in tech.researchReqSRes:
                stratRes.append(getattr(Const, sr))
            tech.researchReqSRes = stratRes
            # build requirements with quantities
            stratRes = {}
            for resource in tech.buildSRes:
                resource_id = getattr(Const, resource)
                # prescription contains constants for big and small amounts
                # possibly within expression
                resource_amount = eval(tech.buildSRes[resource])
                stratRes[resource_id] = resource_amount
            tech.buildSRes = stratRes

            # evaluate researchMod
            if tech.researchMod == "expr":
                tech.researchMod = 1.0
            else:
                tech.researchMod = eval(tech.researchMod)

        # link
        log.message('Linking tech tree...')
        for techID in techs.keys():
            tech = techs[techID]
            for tmpTechID, improvement in tech.researchRequires:
                if techID not in techs[tmpTechID].researchEnables[improvement]:
                    techs[tmpTechID].researchEnables[improvement].append(
                        techID)
            for improvement in tech.researchEnables.keys():
                for tmpTechID in tech.researchEnables[improvement]:
                    if (techID, improvement
                        ) not in techs[tmpTechID].researchRequires:
                        techs[tmpTechID].researchRequires.append(
                            (techID, improvement))

        changed = 1
        while changed:
            changed = 0
            log.debug("Tech disable iteration")
            for techID in techs:
                tech = techs[techID]
                for tech2ID in tech.researchDisables:
                    tech2 = techs[tech2ID]
                    if techID not in tech2.researchDisables and techID != tech2ID:
                        tech2.researchDisables.append(techID)
                        changed = 1
                        log.debug("Adding", tech2ID, "DISABLES", techID,
                                  ", NOW", tech2.researchDisables)
                    for tech3ID in tech2.researchDisables:
                        tech3 = techs[tech3ID]
                        if tech3ID not in tech.researchDisables and tech3ID != techID:
                            tech.researchDisables.append(tech3ID)
                            changed = 1
                            log.debug("Adding", techID, "DISABLES", tech3ID,
                                      "NOW", tech.researchDisables)

        # save new specification
        log.message('Saving specification...')
        pickle.dump(techs, open(os.path.join(configDir, 'techs.spf'), 'wb'), 1)
        pickle.dump(Tech, open(os.path.join(configDir, 'Tech.spf'), 'wb'), 1)
        fh = open(os.path.join(configDir, 'checksum'), 'w')
        fh.write(chsum.hexdigest())
        fh.close()

        log.message("There is %d technologies" % len(techs))
示例#41
0
def runAIClient(options):
    import time
    import traceback
    import sys
    import os

    # tweak PYTHONPATH
    basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    sys.path.insert(0, os.path.join(basepath, "client/osci"))

    for item in ("libsrvr", "server/lib"):
        path = os.path.join(basepath, item)
        if os.path.exists(path):
            sys.path.insert(0, path)
            break

    from config import Config

    import osci, random, time
    import ige.version
    from ige import log
    import os, os.path
    import re

    # log initialization
    log.message("Starting Outer Space Client", ige.version.versionString)
    log.debug("sys.path =", sys.path)
    log.debug("os.name =", os.name)
    log.debug("sys.platform =", sys.platform)
    log.debug("os.getcwd() =", os.getcwd())
    log.debug("sys.frozen =", getattr(sys, "frozen", None))

    # create required directories
    if not os.path.exists(options.configDir):
        os.makedirs(options.configDir)

    # client
    import ai_client as client
    from igeclient.IClient import IClientException
    if options.ai:
        try:
            ai = __import__("AIs." + options.ai)
            ai = sys.modules["AIs." + options.ai]
        except:
            # This prints the type, value, and stack trace of the
            # current exception being handled.
            traceback.print_exc()
            raise
    else:
        raise Exception, 'You have to provide AI.'

    import ige.ospace.Const as Const

    import gdata
    # reload is here for multiprocessing support (as the process is used more
    # than once
    reload(client)
    gdata.config = Config(os.path.join(options.configDir, 'ais_dummy'))
    client.initialize(options.server, options)

    import gettext
    tran = gettext.NullTranslations()
    tran.install(unicode=1)

    if options.login:
        login = options.login
    else:
        raise Exception, 'You have to provide login.'

    if options.password:
        password = options.password
    else:
        raise Exception, 'You have to provide password.'

    # first get list of sessions, then iterate over them
    # this is to prevent exceptions flooding logs
    # TODO: make session optional argument for main_ai_pool
    if client.login(options.game, login, password):
        activePositions = client.cmdProxy.getActivePositions()
        client.logout()
        if options.test:
            return True
    else:
        return False

    for playerID, galaxyName, playerType in activePositions:
        if options.galaxies and galaxyName not in options.galaxies:
            continue
        client.login(options.game, login, password)
        client.cmdProxy.selectPlayer(playerID)
        client.updateDatabase()
        try:
            ai.run(client)
        except Exception as e:
            # This prints the type, value, and stack trace of the
            # current exception being handled.
            traceback.print_exc()
            raise e
        client.logout()
示例#42
0
def updateDatabaseUnsafe(clearDB=0, force=0):
    """Update database by fetching data from the server."""
    global lastUpdate, nonexistingObj, db
    # get real turn
    result = cmdProxy.getIntroInfo(Const.OID_UNIVERSE)
    if not db:
        dbLocation = os.path.join(options.configDir, 'player_data')
        db = IClientDB.IClientDB(result.cid, result.turn, dbLocation,
                                 cmdProxy.gameID)
    if clearDB:
        db.clear()
    db.turn = result.turn
    #
    if db.turn <= lastUpdate and not force:
        return
    log.message('IClient', 'Updating...')
    lastUpdate = db.turn
    nonexistingObj.clear()
    # start updating...
    messageIgnore(Const.SMESSAGE_NEWTURN)
    messageIgnore(Const.SMESSAGE_NEWMESSAGE)
    callbackObj.onUpdateStarting()
    current = 0
    max = 1
    # compute total objects to be fetched
    max += 6  # clear map, get messages, ...
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Deleting obsolete data..."))
    # delete selected objects
    # reset combatCounters
    for objID in db.keys():
        obj = db[objID]
        if hasattr(obj, "combatCounter"):
            obj.combatCounter = 0
        if not hasattr(obj, 'type'):
            del db[objID]
        elif obj.type in (Const.T_FLEET, Const.T_ASTEROID):
            del db[objID]
        elif hasattr(obj, 'owner') and obj.owner == db.playerID \
            and objID != db.playerID:
            # delete player's objects
            del db[objID]
        else:
            if hasattr(obj, "scanPwr"): obj.scanPwr = 0
            if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
    # update player
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading player data..."))
    db[db.playerID] = get(db.playerID)
    player = db[db.playerID]
    # update from scanner's map
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Updating scanner..."))
    map = cmdProxy.getScannerMap(db.playerID)
    for objID in map:
        db[objID] = map[objID]
    # update player's planets and fleets
    current += 1
    callbackObj.onUpdateProgress(current, max,
                                 _("Downloading planets and fleets data..."))
    for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
        db[obj.oid] = obj
    # TODO: try to load allies's info
    # get messages from server
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading messages..."))
    getMessages()
    log.message('IClient', 'Update finished.')
    callbackObj.onUpdateFinished()
    messageEnable(Const.SMESSAGE_NEWTURN)
    messageEnable(Const.SMESSAGE_NEWMESSAGE)
示例#43
0
def checkForUpdate():
    global totalSize, downloadedSize, progressDlg, currentFilename
    # check platform, only 'nt' is supported for now
    if os.name != 'nt':
        log.message("Unsupported platform '%s' -- will not update" % os.name)
        return
    if "oslauncher" in sys.modules:
        log.message(
            "Application launched from Outer Space Launcher -- will not update"
        )
        return
    if not hasattr(sys, "frozen"):
        log.message("Application not frozen using py2exe -- will not update")
        return
    # remove old update directory
    try:
        shutil.rmtree('_update')
    except:
        pass
    # update mode
    if gdata.config.client.updatemode != None:
        updateMode = gdata.config.client.updatemode
    else:
        updateMode = 'normal'
        gdata.config.client.updatemode = updateMode
    # quit if update is disabled
    if updateMode == 'never':
        return
    # force update on every start. TODO remove - just for Alfa/Beta testing
    updateMode = 'always'
    # check for config
    if gdata.config.client.updateurl == None:
        gdata.config.client.updateurl = 'http://www.ospace.net/files/osclient/latest/'
    url = gdata.config.client.updateurl
    # check for last update
    if gdata.config.client.lastupdate != None:
        lastUpdate = gdata.config.client.lastupdate
    else:
        lastUpdate = 'NEVER'
    now = time.strftime('%Y-%m-%d')
    log.debug('UPDATER', 'Checking last update. Last update:', lastUpdate)
    if lastUpdate == now and updateMode != 'always':
        return
    # init dialog
    progressDlg = dialog.ProgressDlg(gdata.app)
    progressDlg.display('Updating client', 0, 1)
    progressDlg.setProgress('Checking for updates...', 0, 1)
    # read global checksum
    log.debug('UPDATER', 'Downloading %schecksum.global' % url)
    # create urlopener
    proxies = {}
    if gdata.config.proxy.http != None:
        proxies['http'] = gdata.config.proxy.http
    log.debug('UPDATER', 'Using proxies', proxies)
    urlopener = urllib.FancyURLopener(proxies)
    try:
        fh = urlopener.open(url + 'checksum.global')
        latestChsum = fh.read()
        fh.close()
        latestChsum = latestChsum.strip()
    except IOError:
        # cannot update
        log.warning('UPDATER', 'Cannot download file.')
        progressDlg.hide()
        return
    log.debug('UPDATER', 'Downloading checksum.global')
    try:
        fh = open('checksum.global', 'r')
        myChsum = fh.read()
        fh.close()
        myChsum = myChsum.strip()
    except IOError:
        myChsum = None
    log.debug('UPDATER', 'Global chsums:', latestChsum, myChsum)
    if latestChsum == myChsum:
        updateConfig()
        progressDlg.hide()
        return
    # load files chsums
    progressDlg.setProgress('Selecting files to update...', 0, 1)
    log.debug('UPDATER', 'Downloading %schecksum.files' % url)
    try:
        fh = urlopener.open(url + 'checksum.files')
        latestData = fh.read()
        fh.close()
    except IOError:
        log.warning('UPDATER', 'Cannot download file.')
        progressDlg.hide()
        return
    log.debug('UPDATER', 'Downloading checksum.files')
    try:
        fh = open('checksum.files', 'r')
        myData = fh.read()
        fh.close()
    except IOError:
        myData = ''
    # parse
    latestChsums = {}
    recipe = []
    retrieve = []
    totalSize = 0
    for line in latestData.split('\n'):
        if not line: continue
        chsum, file, size = line.strip().split(' ')
        size = int(size)
        latestChsums[file] = (chsum, size)
    for line in myData.split('\n'):
        if not line: continue
        chsum, file, size = line.strip().split(' ')
        size = int(size)
        if latestChsums.has_key(file):
            # file remains, check, if update shall be performed
            if latestChsums[file][0] != chsum or not os.path.exists(file):
                retrieve.append((file, latestChsums[file][1]))
                totalSize += latestChsums[file][1]
                recipe.append('C%s' % file)
            del latestChsums[file]
        else:
            # remove old file
            recipe.append('D%s' % file)
    # new files
    for file in latestChsums.keys():
        retrieve.append((file, latestChsums[file][1]))
        totalSize += latestChsums[file][1]
        recipe.append('C%s' % file)
    # log
    #@log.debug('UPDATER', 'Retrieve', retrieve)
    #@log.debug('UPDATER', 'Total length', totalSize)
    #@log.debug('UPDATER', 'Recipe', recipe)
    # retrieve file by file
    downloadedSize = 0
    for filename, size in retrieve:
        currentFilename = os.path.basename(filename)
        fileUrl = '%s%s' % (url, filename)
        log.debug('UPDATER', 'Downloading', fileUrl)
        progressDlg.setProgress('Downloading file %s...' % currentFilename,
                                downloadedSize, totalSize)
        targetFile = os.path.join('_update', filename)
        try:
            os.makedirs(os.path.dirname(targetFile))
        except OSError:
            pass
        try:
            urlopener.retrieve(fileUrl, targetFile, retrieveCallback)
        except IOError:
            log.warning('UPDATER', 'Cannot download file.')
            progressDlg.hide()
            return
        downloadedSize += size
    # finish
    progressDlg.setProgress('Finishing upgrade...')
    updateConfig()
    # save latest checksums
    fh = open('checksum.global', 'w')
    fh.write(latestChsum)
    fh.close()
    fh = open('checksum.files', 'w')
    fh.write(latestData)
    fh.close()
    # save update
    header = ['_update', '.', 'osc.exe', str(len(recipe))]
    header.extend(recipe)
    fh = open('.update', 'w')
    fh.write(string.join(header, '\n'))
    fh.close()
    # copy update program (if possible)
    try:
        shutil.copy2('_update/update.exe', '.')
        os.remove('_update/update.exe')
    except IOError:
        pass
    # delete data files
    # decide if this is needed
    #log.warning('UPDATER', 'Deleting data files...')
    #for filename in glob.glob('var/[0-9]*.data'):
    #	os.remove(filename)
    #for filename in glob.glob('var/[0-9]*.timestamp'):
    #	os.remove(filename)
    # execute update program
    # TODO does not work os.spawnv(os.P_NOWAIT, 'update.exe', ())
    os.startfile('update.exe')
    progressDlg.hide()
    log.warning('UPDATER', 'Exitting...')
    sys.exit(1)
示例#44
0
def cleanup():
    # shut down game
    try:
        if game:
            log.message('Shutting down game...')
            game.shutdown()

        if msgMngr:
            log.message('Shutting down message manager...')
            msgMngr.shutdown()

        if clientMngr:
            log.message('Shutting down client manager...')
            clientMngr.shutdown()

        if issueMngr:
            log.message('Shutting down issue manager...')
            issueMngr.shutdown()
    except:
        log.exception("Shutdown of the server failed")

    log.message('Shutted down')
    log.message("Cleaning up...")
    # delete my pid
    os.close(pidFd)
    os.remove("var/server.pid")
示例#45
0
def runAIClient(options):
    import time
    import traceback
    import sys
    import os

    # tweak PYTHONPATH
    basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    sys.path.insert(0, os.path.join(basepath, "client/osci"))

    for item in ("libsrvr", "server/lib"):
        path = os.path.join(basepath, item)
        if os.path.exists(path):
            sys.path.insert(0, path)
            break

    from config import Config

    import osci, random, time
    import ige.version
    from ige import log
    import os, os.path
    import re

    # log initialization
    log.message("Starting Outer Space Client", ige.version.versionString)
    log.debug("sys.path =", sys.path)
    log.debug("os.name =", os.name)
    log.debug("sys.platform =", sys.platform)
    log.debug("os.getcwd() =", os.getcwd())
    log.debug("sys.frozen =", getattr(sys, "frozen", None))

    # create required directories
    if not os.path.exists(options.configDir):
        os.makedirs(options.configDir)

    # client
    import ai_client as client
    from igeclient.IClient import IClientException
    if options.ai:
        try:
            ai = __import__("AIs." + options.ai)
            ai = sys.modules["AIs." + options.ai]
        except:
            # This prints the type, value, and stack trace of the
            # current exception being handled.
            traceback.print_exc()
            raise
    else:
        raise Exception, 'You have to provide AI.'

    import ige.ospace.Const as Const

    import gdata
    # reload is here for multiprocessing support (as the process is used more
    # than once
    reload(client)
    gdata.config = Config(os.path.join(options.configDir, 'ais_dummy'))
    client.initialize(options.server, options)

    import gettext
    tran = gettext.NullTranslations()
    tran.install(unicode = 1)

    if options.login:
        login = options.login
    else:
        raise Exception, 'You have to provide login.'

    if options.password:
        password = options.password
    else:
        raise Exception, 'You have to provide password.'

    # first get list of sessions, then iterate over them
    # this is to prevent exceptions flooding logs
    # TODO: make session optional argument for main_ai_pool
    if client.login(options.game, login, password):
        activePositions = client.cmdProxy.getActivePositions()
        client.logout()
        if options.test:
            return True
    else:
        return False

    for playerID, galaxyName, playerType in activePositions:
        if options.galaxies and galaxyName not in options.galaxies:
            continue
        client.login(options.game, login, password)
        client.cmdProxy.selectPlayer(playerID)
        client.updateDatabase()
        try:
            ai.run(client)
        except Exception as e:
            # This prints the type, value, and stack trace of the
            # current exception being handled.
            traceback.print_exc()
            raise e
        client.logout()
示例#46
0
def runAIClient(options):
    import time
    import sys
    import os

    # tweak PYTHONPATH
    basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    sys.path.insert(0, os.path.join(basepath, "client/osci"))

    for item in ("libsrvr", "server/lib"):
        path = os.path.join(basepath, item)
        if os.path.exists(path):
            sys.path.insert(0, path)
            break

    from config import Config

    import osci, random, time
    import ige.version
    from ige import log
    import os, os.path
    import re

    # log initialization
    log.message("Starting Outer Space Client", ige.version.versionString)
    log.debug("sys.path =", sys.path)
    log.debug("os.name =", os.name)
    log.debug("sys.platform =", sys.platform)
    log.debug("os.getcwd() =", os.getcwd())
    log.debug("sys.frozen =", getattr(sys, "frozen", None))

    # create required directories
    if not os.path.exists(options.configDir):
        os.makedirs(options.configDir)

    # client
    import ai_client as client
    import ai_handler
    from igeclient.IClient import IClientException
    if options.ai:
        ai = __import__("AIs." + options.ai)
        ai = sys.modules["AIs." + options.ai]
    else:
        raise Exception, 'You have to provide AI.'

    import ige.ospace.Const as Const

    import gdata
    # reload is here for multiprocessing support (as the process is used more
    # than once
    reload(client)
    gdata.config = Config(os.path.join(options.configDir, 'ais_dummy'))
    client.initialize(options.server, ai_handler, options)

    import gettext
    tran = gettext.NullTranslations()
    tran.install(unicode = 1)

    if options.login:
        login = options.login
    else:
        raise Exception, 'You have to provide login.'

    if options.password:
        password = options.password
    else:
        raise Exception, 'You have to provide password.'

    client.login(options.game, login, password)
    # event loop
    client.updateDatabase()
    ai.run(client)

    client.logout()

    log.debug("Shut down")
示例#47
0
def initTechnologies(path):
	"""Init technologies from XML files in the path"""
	# holder for all technologies
	techs = {}
	# holder for tech IDs
	Tech = IDataHolder()

	# compute checksum
	file = sys.modules[__name__].__file__
	forceLoad = 0
	if os.path.exists(file):
		# regular module
		chsum = sha.new()
		os.path.walk(path, chsumDir, chsum)
	else:
		# packed, cannot access xml specifications
		path = os.path.join('res', 'rules/standard')
		forceLoad = 1

	# read old checksum
	try:
		fh = open(os.path.join(path, 'checksum'), 'rb')
		oldChsum = fh.read()
		fh.close()
	except IOError:
		oldChsum = ''

	# compare
	if forceLoad or chsum.hexdigest() == oldChsum:
		# load old definitions
		log.message('Loading stored specifications from', path)
		techs = pickle.load(open(os.path.join(path, 'techs.spf'), 'rb'))
		Tech = pickle.load(open(os.path.join(path, 'Tech.spf'), 'rb'))

		log.message("There is %d technologies" % len(techs))

		# clean up 'type' in lists
		for key in attrs.keys():
			if type(attrs[key]) == types.ListType and len(attrs[key]) == 1:
				log.debug("Cleaning up", key)
				attrs[key] = []
		return techs, Tech
	# create new ones
	## load technologies definitions

	def processDir(arg, dirname, names):
		if dirname.find(".svn") >= 0:
			log.message("Skipping directory", dirname)
			return
		log.message('Loading XML files from', dirname)
		names.sort()
		for filename in names:
			if os.path.splitext(filename)[1] == '.xml':
				log.message('Parsing XML file', filename)
				contentHandler = TechTreeContentHandler()
				contentHandler.setGlobals(techs, Tech)
				xml.sax.parse(os.path.join(dirname, filename), contentHandler)

	# collect xml files
	os.path.walk(path, processDir, None)

	# clean up 'type' in lists
	for key in attrs.keys():
		if type(attrs[key]) == types.ListType and len(attrs[key]) == 1:
			log.debug("Cleaning up", key)
			attrs[key] = []

	# link tech tree using researchRequires fields
	# construct researchEnables fields
	log.message('Converting symbolic fields...')
	for techID in techs.keys():
		tech = techs[techID]
		# convert symbolic names to numbers
		techIDs = []
		for techSymName in tech.researchRequires:
			#@log.debug('Converting REQ', techSymName)
			symName, improvement = techSymName.split('-')
			techIDs.append((getattr(Tech, symName), int(improvement)))
		tech.researchRequires = techIDs
		techIDs = {1: [], 2:[], 3:[], 4:[], 5:[], 6:[]}
		for techSymName in tech.researchEnables:
			#@log.debug('Converting EN', techSymName)
			improvement, symName = techSymName.split('-')
			techIDs[int(improvement)].append(getattr(Tech, symName))
		tech.researchEnables = techIDs
		techIDs = []
		for techSymName in tech.researchDisables:
			techIDs.append(getattr(Tech, techSymName))
		tech.researchDisables = techIDs
		techIDs = []
		if tech.unpackStruct:
			tech.unpackStruct = getattr(Tech, tech.unpackStruct)
		else:
			tech.unpackStruct = 0
		# strat. resources
		stratRes = []
		for sr in tech.researchReqSRes:
			stratRes.append(getattr(Const, sr))
		tech.researchReqSRes = stratRes
		stratRes = []
		for sr in tech.buildSRes:
			stratRes.append(getattr(Const, sr))
		tech.buildSRes = stratRes
		# evaluate researchMod
		if tech.researchMod == "expr":
			tech.researchMod = 1.0
		else:
			tech.researchMod = eval(tech.researchMod)
		#~ # convert weapons
		#~ techIDs = []
		#~ for weaponName in tech.weapons:
			#~ techIDs.append(getattr(Tech, weaponName))
		#~ tech.weapons = techIDs

	# link
	log.message('Linking tech tree...')
	for techID in techs.keys():
		tech = techs[techID]
		#@log.debug(techID, 'Req', tech.researchRequires)
		#@log.debug(techID, 'En', tech.researchEnables)
		for tmpTechID, improvement in tech.researchRequires:
			if techID not in techs[tmpTechID].researchEnables[improvement]:
				#@log.debug('Adding', tmpTechID, improvement, 'ENABLES', techID)
				techs[tmpTechID].researchEnables[improvement].append(techID)
		for improvement in tech.researchEnables.keys():
			for tmpTechID in tech.researchEnables[improvement]:
				if (techID, improvement) not in techs[tmpTechID].researchRequires:
					#@log.debug('Adding', tmpTechID, 'REQUIRES', techID, improvement)
					techs[tmpTechID].researchRequires.append((techID, improvement))

	changed = 1
	while changed:
		changed = 0
		log.debug("Tech disable iteration")
		for techID in techs:
			tech = techs[techID]
			for tech2ID in tech.researchDisables:
				tech2 = techs[tech2ID]
				if techID not in tech2.researchDisables and techID != tech2ID:
					tech2.researchDisables.append(techID)
					changed = 1
					log.debug("Adding", tech2ID, "DISABLES", techID, ", NOW", tech2.researchDisables)
				for tech3ID in tech2.researchDisables:
					tech3 = techs[tech3ID]
					if tech3ID not in tech.researchDisables and tech3ID != techID:
						tech.researchDisables.append(tech3ID)
						changed = 1
						log.debug("Adding", techID, "DISABLES", tech3ID, "NOW", tech.researchDisables)
	# just for debug
	#for techID in techs.keys():
	#	tech = techs[techID]
	#	log.debug('Link:', techID, tech.isStarting, tech.researchRequires, tech.researchEnables)

	# save new specification
	log.message('Saving specification...')
	pickle.dump(techs, open(os.path.join(path, 'techs.spf'), 'wb'), 1)
	pickle.dump(Tech, open(os.path.join(path, 'Tech.spf'), 'wb'), 1)
	fh = open(os.path.join(path, 'checksum'), 'wb')
	fh.write(chsum.hexdigest())
	fh.close()

	log.message("There is %d technologies" % len(techs))

	return techs, Tech
示例#48
0
def _generateKeys(size):
    global publicKey, privateKey
    # no keys, let's generate them
    log.message("Generating RSA keys of size {0}, please wait...".format(size))
    publicKey, privateKey = rsa.newkeys(size)
示例#49
0
def logout():
	if cmdProxy and cmdProxy.logged:
		cmdProxy.logout()
	if db:
		log.message('OSClient', 'Saving database')
		db.save()
示例#50
0
    def backup(self, backupPath):
        """ Creates bzip2 archive of ais_list file and ai_data directory

        """
        log.debug('Creating backup {0}-ais.osbackup'.format(backupPath))
        tar = tarfile.open('{0}-ais.osbackup'.format(backupPath), 'w:bz2')
        tar.add(os.path.join(self.configDir, self.listname))
        tar.add(os.path.join(self.configDir, 'ai_data', self.gameName))
        tar.close()

    def restore(self, backupPath):
        """ Extracts data of the ai players, as well as the ais_list file.

        """
        os.remove(os.path.join(self.configDir, self.listname))
        shutil.rmtree(os.path.join(self.configDir, 'ai_data', self.gameName))
        log.message('Restoring AI backup {0}'.format(backupPath))
        tar = tarfile.open(backupPath, 'r:bz2')
        tar.extractall()
        tar.close()
        self.records = []
        # parsing the file
        try:
            self.records = json.load(open(os.path.join(self.configDir, self.listname), "r"), object_hook=aiRecordDecoder)
        except Exception, e:
            listfile = open(os.path.join(self.configDir, self.listname), "a")
            listfile.close()
        log.message('AI backup restored')

示例#51
0
def updateDatabaseUnsafe(clearDB = 0, force = 0):
	"""Update database by fetching data from the server."""
	global lastUpdate, nonexistingObj, db
	# get real turn
	result = cmdProxy.getIntroInfo(OID_UNIVERSE)
	if not db:
		db = IClientDB.IClientDB(result.cid, result.turn, options.configDir)
	if clearDB:
		db.clear()
	db.turn = result.turn
	#
	if db.turn <= lastUpdate and not force:
		return
	log.message('IClient', 'Updating...')
	lastUpdate = db.turn
	nonexistingObj.clear()
	# start updating...
	messageIgnore(SMESSAGE_NEWTURN)
	messageIgnore(SMESSAGE_NEWMESSAGE)
	callbackObj.onUpdateStarting()
	current = 0
	max = 1
	# compute total objects to be fetched
	max += 6 # clear map, get messages, ...
	current += 1
	callbackObj.onUpdateProgress(current, max, _("Deleting obsolete data..."))
	# delete selected objects
	# reset combatCounters
	for objID in db.keys():
		obj = db[objID]
		if hasattr(obj, "combatCounter"):
			obj.combatCounter = 0
		if not hasattr(obj, 'type'):
			del db[objID]
		elif obj.type in (T_FLEET, T_ASTEROID):
			del db[objID]
		elif hasattr(obj, 'owner') and obj.owner == db.playerID \
			and objID != db.playerID:
			# delete player's objects
			del db[objID]
		else:
			if hasattr(obj, "scanPwr"): obj.scanPwr = 0
			if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
	# update player
	current += 1
	callbackObj.onUpdateProgress(current, max, _("Downloading player data..."))
	db[db.playerID] = get(db.playerID)
	player = db[db.playerID]
	# update from scanner's map
	current += 1
	callbackObj.onUpdateProgress(current, max, _("Updating scanner..."))
	map = cmdProxy.getScannerMap(db.playerID)
	for objID in map:
		db[objID] = map[objID]
	# update player's planets and fleets
	current += 1
	callbackObj.onUpdateProgress(current, max, _("Downloading planets and fleets data..."))
	for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
		db[obj.oid] = obj
	#~ # compute system's positions
	#~ current += 1
	#~ callbackObj.onUpdateProgress(current, max, _("Updating astronomical coordinates..."))
	#~ systems = {}
	#~ for objID in db.keys():
		#~ obj = db[objID]
		#~ if obj.type == T_SYSTEM or obj.type == T_PLANET:
			#~ if obj.type == T_SYSTEM:
				#~ galaxy = get(obj.compOf)
				#~ system = obj
			#~ else:
				#~ if obj.compOf in systems:
					#~ system = systems[obj.compOf]
				#~ else:
					#~ system = get(obj.compOf, canBePublic = 0)
					#~ systems[obj.compOf] = system
				#~ if hasattr(system, "compOf"):
					#~ galaxy = get(system.compOf)
				#~ else:
					#~ continue
			#~ angle = system.sAngle / 1000.0 + (db.turn / Rules.rotationMod) * system.dAngle / 1000.0
			#~ obj.x = galaxy.x + system.dist * math.cos(angle) / 1000.0
			#~ obj.y = galaxy.y + system.dist * math.sin(angle) / 1000.0
	#~ del systems
	# TODO: try to load allies's info
	# get messages from server
	current += 1
	callbackObj.onUpdateProgress(current, max, _("Skipping messages..."))
	# getMessages()
	# clean maps on server
	current += 1
	callbackObj.onUpdateProgress(current, max, _("Clearing data on the server..."))
	try:
		cmdProxy.setResolution(db.playerID,gdata.scrnSize[0],gdata.scrnSize[1])
	except:
		log.debug('Server does not yet support resolution tracking')
	# TODO not needed - delete cmdProxy.clearScannerMap(db.playerID)
	# finished
	log.message('IClient', 'Update finished.')
	callbackObj.onUpdateFinished()
	messageEnable(SMESSAGE_NEWTURN)
	messageEnable(SMESSAGE_NEWMESSAGE)
示例#52
0
def saveDB():
    if db:
        log.message('OSClient', 'Saving database')
        db.save()
示例#53
0
def runClient(options):

    # log initialization
    log.message("Starting Outer Space Client", ige.version.versionString)
    log.debug("sys.path =", sys.path)
    log.debug("os.name =", os.name)
    log.debug("sys.platform =", sys.platform)
    log.debug("os.getcwd() =", os.getcwd())
    log.debug("sys.frozen =", getattr(sys, "frozen", None))

    # create required directories
    if not os.path.exists(options.configDir):
        os.makedirs(options.configDir)
    log.debug("options.configDir =", options.configDir)

    running = 1
    first = True
    #while running:
    if not first:
        reload(osci)
    # parse configuration
    if first:
        import osci.gdata as gdata
    else:
        reload(gdata)

    gdata.config = Config(
        os.path.join(options.configDir, options.configFilename))
    gdata.config.game.server = options.server

    setDefaults(gdata, options)

    language = gdata.config.client.language
    import gettext
    log.debug('OSCI', 'Installing translation for:', language)
    if language == 'en':
        log.debug('OSCI', 'English is native - installing null translations')
        tran = gettext.NullTranslations()
    else:
        try:
            tran = gettext.translation('OSPACE',
                                       resources.get('translations'),
                                       languages=[language])
        except IOError:
            log.warning('OSCI', 'Cannot find catalog for', language)
            log.message('OSCI', 'Installing null translations')
            tran = gettext.NullTranslations()

    tran.install(unicode=1)

    #initialize pygame and prepare screen
    if (gdata.config.defaults.sound == "yes") or (gdata.config.defaults.music
                                                  == "yes"):
        pygame.mixer.pre_init(44100, -16, 2, 4096)

    os.environ['SDL_VIDEO_ALLOW_SCREENSAVER'] = '1'
    os.environ['SDL_DEBUG'] = '1'
    pygame.init()

    flags = pygame.SWSURFACE

    DEFAULT_SCRN_SIZE = (800, 600)
    gdata.scrnSize = DEFAULT_SCRN_SIZE
    if gdata.config.display.resolution == "FULLSCREEN":
        gdata.scrnSize = (0, 0)
        flags |= pygame.FULLSCREEN
    elif gdata.config.display.resolution is not None:
        width, height = gdata.config.display.resolution.split('x')
        gdata.scrnSize = (int(width), int(height))

    if gdata.config.display.depth == None:
        # guess best depth
        bestdepth = pygame.display.mode_ok(gdata.scrnSize, flags)
    else:
        bestdepth = int(gdata.config.display.depth)

    # initialize screen
    try:
        screen = pygame.display.set_mode(gdata.scrnSize, flags, bestdepth)
        # gdata.scrnSize is used everywhere to setup windows
        gdata.scrnSize = screen.get_size()
    except pygame.error:
        # for example if fullscreen is selected with resolution bigger than display
        # TODO: as of now, fullscreen has automatic resolution
        gdata.scrnSize = DEFAULT_SCRN_SIZE
        screen = pygame.display.set_mode(gdata.scrnSize, flags, bestdepth)
    gdata.screen = screen
    log.debug('OSCI', 'Driver:', pygame.display.get_driver())
    log.debug('OSCI', 'Using depth:', bestdepth)
    log.debug('OSCI', 'Display info:', pygame.display.Info())

    pygame.mouse.set_visible(1)

    pygame.display.set_caption(_('Outer Space %s') % ige.version.versionString)

    # set icon
    pygame.display.set_icon(
        pygame.image.load(resources.get('icon48.png')).convert_alpha())

    # UI stuff
    if first:
        import pygameui as ui
    else:
        reload(ui)

    setSkinTheme(gdata, ui)

    app = ui.Application(update, theme=ui.SkinableTheme)
    app.background = defineBackground()
    app.draw(gdata.screen)
    app.windowSurfaceFlags = pygame.SWSURFACE | pygame.SRCALPHA
    gdata.app = app

    pygame.event.clear()

    # resources
    import osci.res

    osci.res.initialize()

    # load resources
    import osci.dialog
    dlg = osci.dialog.ProgressDlg(gdata.app)
    osci.res.loadResources(dlg)
    dlg.hide()
    osci.res.prepareUIIcons(ui.SkinableTheme.themeIcons)

    while running:
        if first:
            import osci.client, osci.handler
            from igeclient.IClient import IClientException
        else:
            reload(osci.client)
            reload(osci.handler)
        osci.client.initialize(gdata.config.game.server, osci.handler, options)

        # create initial dialogs
        if first:
            import osci.dialog
        else:
            reload(osci.dialog)
        gdata.savePassword = gdata.config.game.lastpasswordcrypted != None

        if options.login and options.password:
            gdata.config.game.lastlogin = options.login
            gdata.config.game.lastpassword = options.password
            gdata.config.game.lastpasswordcrypted = binascii.b2a_base64(
                options.password).strip()
            gdata.config.game.autologin = '******'
            gdata.savePassword = '******'

        loginDlg = osci.dialog.LoginDlg(gdata.app)
        updateDlg = osci.dialog.UpdateDlg(gdata.app)

        # event loop
        update()

        lastSave = time.clock()
        # set counter to -1 to trigger Update dialog (see "if" below)
        counter = -1
        needsRefresh = False
        session = 1
        first = False
        while running and session:
            try:
                counter += 1
                if counter == 0:
                    # display initial dialog in the very first cycle
                    updateDlg.display(caller=loginDlg, options=options)
                # process as many events as possible before updating
                evt = pygame.event.wait()
                evts = pygame.event.get()
                evts.insert(0, evt)

                forceKeepAlive = False
                saveDB = False

                for evt in evts:
                    if evt.type == pygame.QUIT:
                        running = 0
                        break
                    if evt.type == (
                            ui.USEREVENT) and evt.action == "localExit":
                        session = False
                        break
                    if evt.type == pygame.ACTIVEEVENT:
                        if evt.gain == 1 and evt.state == 6:
                            # pygame desktop window focus event
                            needsRefresh = True
                    if evt.type == pygame.KEYUP and evt.key == pygame.K_F12:
                        if not pygame.key.get_mods() & pygame.KMOD_CTRL:
                            running = 0
                            break
                    if evt.type == pygame.KEYUP and evt.key == pygame.K_F9:
                        forceKeepAlive = True
                    evt = gdata.app.processEvent(evt)

                if gdata.app.needsUpdate() or needsRefresh:
                    needsRefresh = False
                    update()
                # keep alive connection
                osci.client.keepAlive(forceKeepAlive)

                # save DB every 4 hours in case of a computer crash
                # using "counter" to limit calls to time.clock() to approximately every 10-15 minutes
                if counter > 5000:
                    # set this to zero so we don't display Update dialog
                    counter = 0
                    if time.clock() - lastSave > 14400:
                        saveDB = True
                if saveDB:
                    osci.client.saveDB()
                    lastSave = time.clock()

            except IClientException, e:
                osci.client.reinitialize()
                gdata.app.setStatus(e.args[0])
                loginDlg.display(message=e.args[0])
            except Exception, e:
                log.warning('OSCI', 'Exception in event loop')
                if not isinstance(e, SystemExit) and not isinstance(
                        e, KeyboardInterrupt):
                    log.debug("Processing exception")
                    # handle exception
                    import traceback, StringIO
                    fh = StringIO.StringIO()
                    exctype, value, tb = sys.exc_info()
                    funcs = [entry[2] for entry in traceback.extract_tb(tb)]
                    faultID = "%06d-%03d" % (
                        hash("/".join(funcs)) % 1000000,
                        traceback.extract_tb(tb)[-1][1] % 1000,
                    )
                    del tb
                    # high level info
                    print >> fh, "Exception ID:", faultID
                    print >> fh
                    print >> fh, "%s: %s" % (exctype, value)
                    print >> fh
                    print >> fh, "--- EXCEPTION DATA ---"
                    # dump exception
                    traceback.print_exc(file=fh)
                    excDlg = osci.dialog.ExceptionDlg(gdata.app)
                    excDlg.display(faultID, fh.getvalue())
                    del excDlg  # reference to the dialog holds app's intance
                    fh.close()
                    del fh
                else:
                    break
示例#54
0
def logout():
    if cmdProxy and cmdProxy.logged:
        cmdProxy.logout()
    if db:
        log.message('OSClient', 'Saving database')
        db.save()
示例#55
0
	def processFINALPhase(self, tran, obj, data):
		if obj.timeEnabled:
			#try/except so that entire final process doesn't break on error in sub-phase
			try:
				self.cmd(obj).processRSRCHPhase(tran, obj, data)
			except:
				log.warning('Cannot execute FINAL/RSRCH on %d' % (obj.oid))
			try:
				self.cmd(obj).processDIPLPhase(tran, obj, data)
			except:
				log.warning('Cannot execute FINAL/DIPL on %d' % (obj.oid))
		# efficiency
		obj.prodEff = 1.0
		obj.sciEff = 1.0
		if obj.imperator == 1:
			log.debug(obj.oid, "Leader bonus")
			obj.prodEff += Rules.galLeaderBonus
			obj.sciEff += Rules.galLeaderBonus
		elif obj.imperator >= 2:
			log.debug(obj.oid, "Imperator bonus")
			obj.prodEff += Rules.galImperatorBonus
			obj.sciEff += Rules.galImperatorBonus
		#@log.debug("Fleet upgrade pool", obj.oid, obj.fleetUpgradePool, obj.fleetUpgradeInProgress)
		# compute some stats
		# TODO remove, RAW SCI PTS represented now obj.stats.prodSci = obj.effSciPoints
		obj.stats.planets = len(obj.planets)
		# fleet support
		#@log.debug("Fleet support", obj.oid, obj.stats.fleetSupportProd, obj.stats.prodProd)
		if obj.stats.fleetSupportProd > 0 and obj.stats.prodProd > 0:
			# TODO 0.1 shall be dependend on the race / government type
			obj.prodEff += min(0.1 - float(obj.stats.fleetSupportProd + obj.fleetUpgradePool * Rules.operProdRatio) / obj.stats.prodProd, 0.0)
		# delete non active player
		if obj.lastLogin + Rules.playerTimeout < time.time():
			log.message("Resigning inactive player", obj.name, obj.oid)
			# TODO send a message?
			self.cmd(obj).resign(tran, obj)
		# delete nonactive newbie player
		if obj.lastLogin + Rules.novicePlayerTimeout < time.time() \
			and len(obj.planets) < 4:
			log.message("Resigning inactive novice player", obj.name, obj.oid)
			# TODO send a message?
			self.cmd(obj).resign(tran, obj)
		# acquire government power
		if obj.planets:
			planet = tran.db[obj.planets[0]]
			for slot in planet.slots:
				tech = Rules.techs[slot[STRUCT_IDX_TECHID]]
				if tech.govPwr > 0 and slot[STRUCT_IDX_STATUS] & STRUCT_STATUS_ON:
					eff = Utils.getTechEff(tran, slot[STRUCT_IDX_TECHID], obj.oid)
					obj.govPwr = max(int(tech.govPwr * eff * (slot[STRUCT_IDX_OPSTATUS] / 100.0)), obj.govPwr)
		# compute government controll range
		if not hasattr(obj,"tmpPopDistr"): #when player is force-resigned, tmpPopDistr is unset. This is easiest fix.
			obj.tmpPopDistr = {}
		ranges = obj.tmpPopDistr.keys()
		ranges.sort()
		sum = 0
		range = 1
		for range in ranges:
			sum += obj.tmpPopDistr[range]
			if sum > obj.govPwr:
				break
		obj.govPwrCtrlRange = max(1, range)
		if sum < obj.govPwr and sum > 0:
			#@log.debug(obj.oid, "GovPwr compensation", obj.govPwrCtrlRange, obj.govPwr, sum)
			obj.govPwrCtrlRange = int(obj.govPwrCtrlRange * obj.govPwr / float(sum))
		#@log.debug(obj.oid, "GovPwr control range", obj.govPwrCtrlRange)
		# compute prodBonus and sciBonus
		sum = 0
		for range in ranges:
			sum += obj.tmpPopDistr[range]
		if sum < obj.govPwr and sum > 0:
			ratio = float(obj.govPwr - sum) / obj.govPwr
			#@log.debug(obj.oid, "SMALL EMPIRE BONUS", ratio, "govPwr", obj.govPwr, "sum", sum)
			# TODO let user to define how much to invest into prod and to sci
			obj.prodEff += ratio / 2
			obj.sciEff += ratio / 2
		del obj.tmpPopDistr # delete temporary attribute
		# increase prod eff from pacts
		# CPs from allies
		sum = 0
		for partnerID in obj.diplomacyRels:
			if self.cmd(obj).isPactActive(tran, obj, partnerID, PACT_MINOR_CP_COOP):
				partner = tran.db[partnerID]
				pactSpec = Rules.pactDescrs[PACT_MINOR_CP_COOP]
				sum += min(
					partner.stats.prodProd * pactSpec.effectivity,
					obj.stats.prodProd * pactSpec.effectivity,
				)
			if self.cmd(obj).isPactActive(tran, obj, partnerID, PACT_MAJOR_CP_COOP):
				partner = tran.db[partnerID]
				pactSpec = Rules.pactDescrs[PACT_MAJOR_CP_COOP]
				sum += min(
					partner.stats.prodProd * pactSpec.effectivity,
					obj.stats.prodProd * pactSpec.effectivity,
				)
		# apply production increase pool
		obj.prodIncreasePool += sum
		if obj.stats.prodProd > 0:
			ratio = (Rules.unusedProdMod * obj.prodIncreasePool) / obj.stats.prodProd
			real = min(ratio, math.sqrt(ratio))
			#@log.debug(obj.oid, "Increase production by", ratio, "real", real)
			obj.prodEff += real
		# clean up prodEff if prodEff < 0 (prevent abuse)
		if obj.prodEff < 0:
			obj.prodEff = 0.0
		# clean up ship redirections
		systems = {}
		for planetID in obj.planets:
			systems[tran.db[planetID].compOf] = None
		for systemID in obj.shipRedirections.keys():
			if systemID not in systems:
				del obj.shipRedirections[systemID]

		# delete allied bouys
		obj.alliedBuoys = {}

		# find all allies
		for partnerID in obj.diplomacyRels.keys():
			dipl = obj.diplomacyRels[partnerID]
			getAllyBuoys = False
			getScannerBuoys = False
			if dipl.relation >= REL_ALLY_LO:
				getAllyBuoys = True
			if self.isPactActive(tran, obj, partnerID, PACT_SHARE_SCANNER):
				getScannerBuoys = True
			if (getAllyBuoys or getScannerBuoys):
				partner = tran.db[partnerID]
				if hasattr(partner, "buoys"):
					for systemID in partner.buoys.keys():
						toAllyBuoy = BUOY_NONE
						if getAllyBuoys and partner.buoys[systemID][1] == BUOY_TO_ALLY:
							toAllyBuoy = (partner.buoys[systemID][0], BUOY_FROM_ALLY, partner.name)
						elif getScannerBuoys and partner.buoys[systemID][1] == BUOY_TO_SCANNERSHARE:
							toAllyBuoy = (partner.buoys[systemID][0], BUOY_FROM_ALLY, partner.name)
						if toAllyBuoy != BUOY_NONE:
							if systemID in obj.alliedBuoys:
								obj.alliedBuoys[systemID].append(toAllyBuoy)
							else:
								obj.alliedBuoys[systemID] = [toAllyBuoy]
		return None
示例#56
0
def updateDatabaseUnsafe(clearDB = 0, force = 0):
    """Update database by fetching data from the server."""
    global lastUpdate, nonexistingObj, db
    # get real turn
    result = cmdProxy.getIntroInfo(Const.OID_UNIVERSE)
    if not db:
        dbLocation = os.path.join(options.configDir, 'player_data')
        db = IClientDB.IClientDB(result.cid, result.turn, dbLocation, cmdProxy.gameID)
    if clearDB:
        db.clear()
    db.turn = result.turn
    #
    if db.turn <= lastUpdate and not force:
        return
    log.message('IClient', 'Updating...')
    lastUpdate = db.turn
    nonexistingObj.clear()
    # start updating...
    messageIgnore(Const.SMESSAGE_NEWTURN)
    messageIgnore(Const.SMESSAGE_NEWMESSAGE)
    callbackObj.onUpdateStarting()
    current = 0
    max = 1
    # compute total objects to be fetched
    max += 6 # clear map, get messages, ...
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Deleting obsolete data..."))
    # delete selected objects
    # reset combatCounters
    for objID in db.keys():
        obj = db[objID]
        if hasattr(obj, "combatCounter"):
            obj.combatCounter = 0
        if not hasattr(obj, 'type'):
            del db[objID]
        elif obj.type in (Const.T_FLEET, Const.T_ASTEROID):
            del db[objID]
        elif hasattr(obj, 'owner') and obj.owner == db.playerID \
            and objID != db.playerID:
            # delete player's objects
            del db[objID]
        else:
            if hasattr(obj, "scanPwr"): obj.scanPwr = 0
            if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
    # update player
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading player data..."))
    db[db.playerID] = get(db.playerID)
    player = db[db.playerID]
    # update from scanner's map
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Updating scanner..."))
    map = cmdProxy.getScannerMap(db.playerID)
    for objID in map:
        db[objID] = map[objID]
    # update player's planets and fleets
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading planets and fleets data..."))
    for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
        db[obj.oid] = obj
    # TODO: try to load allies's info
    # get messages from server
    current += 1
    callbackObj.onUpdateProgress(current, max, _("Downloading messages..."))
    getMessages()
    log.message('IClient', 'Update finished.')
    callbackObj.onUpdateFinished()
    messageEnable(Const.SMESSAGE_NEWTURN)
    messageEnable(Const.SMESSAGE_NEWMESSAGE)
示例#57
0
def runServer(options):
    import os
    import shutil
    import sys
    import time
    import passlib # checking it early in the process

    # setup system path
    baseDir = os.path.abspath(os.path.dirname(__file__))

    sys.path.insert(0, os.path.join(baseDir, "lib"))
    sys.path.insert(0, os.path.join(baseDir, "..", "client-ai"))
    sys.path.insert(0, os.path.join(baseDir, "data"))

    import os, atexit


    #configure gc
    #import gc
    #gc.set_debug(gc.DEBUG_STATS | gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE |
    #    gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS)


    # legacy logger
    from ige import log
    log.setMessageLog(os.path.join(options.configDir,'logs/messages.log'))
    log.setErrorLog(os.path.join(options.configDir,'logs/errors.log'))

    import ige.version
    log.message("Outer Space %s" % ige.version.versionString)
    #~ # standard logger
    #~ import logging, logging.handlers
    #~ log = logging.getLogger()
    #~ log.setLevel(logging.DEBUG)
    #~ # file handler
    #~ h = logging.handlers.RotatingFileHandler(os.path.join(options.configDir,'log/server.log'), 'a', 16 * 1024 * 1024, 5)
    #~ h.setLevel(logging.INFO)
    #~ h.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(name)s %(message)s'))
    #~ log.addHandler(h)
    #~ # stdout handler (TODO: disable in productin server)
    #~ h = logging.StreamHandler(sys.stdout)
    #~ h.setLevel(logging.DEBUG)
    #~ h.setFormatter(logging.Formatter('%(created)d %(levelname)-5s %(name)-8s %(message)s'))
    #~ log.addHandler(h)


    # record my pid
    pidFd = os.open(os.path.join(options.configDir,"server.pid"), os.O_CREAT | os.O_EXCL | os.O_WRONLY)
    os.write(pidFd, str(os.getpid()))
    # TODO: check if server.pid points to the running process

    game = None
    msgMngr = None
    clientMngr = None
    issueMngr = None
    bookingMngr = None

    # define and register exit function

    def _save():
    # shut down game
        try:
            if game:
                log.message('Shutting down game...')
                game.shutdown()

            if msgMngr:
                log.message('Shutting down message manager...')
                msgMngr.shutdown()

            if clientMngr:
                log.message('Shutting down client manager...')
                clientMngr.shutdown()

            if issueMngr:
                log.message('Shutting down issue manager...')
                issueMngr.shutdown()

            if bookingMngr:
                log.message('Shutting down booking manager...')
                bookingMngr.shutdown()
        except:
            log.exception("Shutdown of the server failed")

        config.save()
        log.message('Shutted down')
        log.message("Cleaning up...")

    def _cleanup(pidFd):
        _save()
        # delete my pid
        os.close(pidFd)
        os.remove(os.path.join(options.configDir,"server.pid"))

    cleanup = _cleanup

    atexit.register(cleanup, pidFd)

    #~fh = open(pidFilename, 'w')
    #~print >> fh, os.getpid()
    #~fh.close()

    # startup game
    log.debug('Importing IGE modules...')

    # set runtime mode
    ige.setRuntimeMode(options.mode)

    import ige.RPCServer as server
    import ige
    from ige.ClientMngr import ClientMngr
    from ige.MsgMngr import MsgMngr
    from ige.IssueMngr import IssueMngr
    from ige.ospace.GameMngr import GameMngr
    from ige.BookingMngr import BookingMngr

    # read configuration
    from ige.Config import Config
    log.message("Reading configuration from", os.path.join(options.configDir, options.configFilename))
    config = Config(os.path.join(options.configDir, options.configFilename))


    gameName = 'Alpha'

    # open database
    from ige.SQLiteDatabase import Database, DatabaseString

    if not config.vip.password:
        config.vip.password = ''

    log.debug("Creating databases...")
    gameDB = Database(os.path.join(options.configDir,"db_data"), "game_%s" % gameName, cache = 15000)
    clientDB = DatabaseString(os.path.join(options.configDir,"db_data"), "accounts", cache = 100)
    msgDB = DatabaseString(os.path.join(options.configDir,"db_data"), "messages", cache = 1000)
    bookingDB = DatabaseString(os.path.join(options.configDir,"db_data"), "bookings", cache = 100)

    if options.restore:
        gameDB.restore("%s-game_%s.osbackup" % (options.restore, gameName))
        clientDB.restore("%s-accounts.osbackup" % options.restore)
        # TODO: remove afer fix of the message database
        # the following code imports to the message database only valid entries
        # and forces mailbox scan
        incl = [1]
        incl.extend(gameDB[1].galaxies)
        incl.extend(gameDB[1].players)
        def include(k, l = incl):
            for i in l:
                if k.startswith("%s-%d-" % (gameName, i)) or (k == "%s-%d" % (gameName, i)):
                    return True
            return False
        msgDB.restore("%s-messages.osbackup" % options.restore, include = include)
        bookingDB.restore("%s-bookings.osbackup" % options.restore, include = include)

    # initialize game
    log.message('Initializing game \'%s\'...' % gameName)

    log.debug("Initializing issue manager")
    issueMngr = IssueMngr()
    log.debug("Initializing client manager")
    clientMngr = ClientMngr(clientDB, config.server.authmethod, options.configDir)
    log.debug("Initializing message manager")
    msgMngr = MsgMngr(msgDB)
    log.debug("Initializing game manager")
    game = GameMngr(gameName, config, clientMngr, msgMngr, gameDB, options.configDir)
    log.debug("Initializing booking manager")
    bookingMngr = BookingMngr(clientMngr, game, bookingDB)

    # either forced reset, or uninitialized server
    if options.reset or not gameDB.keys():
        # reset game
        log.message('Resetting game \'%s\'...' % gameName)
        game.reset()

    # remote web directory should be populated for the first time
    # with contents of server/website
    # but then, no overwrite should happen, as we want customization
    # to be painless
    if not os.path.exists(os.path.join(options.configDir, 'website')):
        log.debug("Populating website directory")
        actual_dir = os.path.dirname(os.path.realpath(__file__))
        shutil.copytree(os.path.join(actual_dir, 'website'), os.path.join(options.configDir, 'website'))
    # normal operations
    game.init()

    if options.upgrade:
        game.upgrade()
        msgMngr.upgrade()
        bookingMngr.upgrade()

    game.start()

    server.init(clientMngr, bookingMngr)
    server.register(game)

    server.xmlrpcPublish('clientmngr', clientMngr)
    server.xmlrpcPublish('issuemngr', issueMngr)
    log.message('Initialized. Starting server...')

    try:
        import psyco
        psyco.full()
        log.message("Using psyco with full acceleration")
    except ImportError:
        log.message("NOT using psyco")
    server.start(options.configDir)