Пример #1
0
	def changeOwner(self, tran, obj, ownerID, force = 0):
		oldOwnerID = obj.owner
		if obj.owner == ownerID:
			# the owner is the same
			return
		elif obj.owner != OID_NONE and force == 0:
			# this planet is already owned!
			# TODO resolve conflict (based on player relations)
			raise GameException('Planet is already owned by another commander.')
		elif obj.owner != OID_NONE and force == 1:
			# remove planet from old owner
			try:
				oldOwner = tran.db[obj.owner]
				oldOwner.planets.remove(obj.oid)
				if tran.db.has_key(obj.owner):
					Utils.sendMessage(tran, obj, MSG_LOST_PLANET, obj.oid, None)
			except Exception:
				log.warning("Cannot remove planet from owner", obj.oid, obj.owner)
				oldOwnerID = OID_NONE
		# reset timer
		obj.ownerSince = tran.db[OID_UNIVERSE].turn
		# add planet to new owner's empire
		if ownerID != OID_NONE:
			newOwner = tran.db[ownerID]
			newOwner.planets.append(obj.oid)
		# reset some attributes
		obj.owner = ownerID
		obj.revoltLen = 0 # no revolt
		obj.prodQueue = [] # clear production queue
		if ownerID != OID_NONE:
			# notify player
			Utils.sendMessage(tran, obj, MSG_GAINED_PLANET, obj.oid, None)
Пример #2
0
def _checkValidity(ship, tech, installations, equipCounter, raiseExs):
    if not raiseExs:
        return
    # check min hull req
    elif tech.minHull > ship.combatClass:
        log.warning("Cannot add tech", tech.id, tech.name)
        raise GameException("Minimum hull requirement not satisfied.")
    # check max hull req
    elif tech.maxHull < ship.combatClass:
        log.warning("Cannot add tech", tech.id, tech.name)
        raise GameException("Maximum hull requirement not satisfied.")
    # check maximum installations
    elif tech.maxInstallations and installations[
            tech.id] > tech.maxInstallations:
        raise GameException(
            "Maximum number of equipment installations exceeded.")
    #check maximum type installations
    elif tech.subtype == "seq_mod" and tech.equipType in Rules.maxEquipType:
        try:
            equipCounter[tech.equipType] += 1
        except KeyError:
            equipCounter[tech.equipType] = 1
        if equipCounter[tech.equipType] > Rules.maxEquipType[tech.equipType]:
            raise GameException(
                "Maximum number of restricted type equipment installations exceeded: %s."
                % tech.equipType)
Пример #3
0
def getMessages():
    # construct list of mailboxes
    mailboxes = []
    mailboxes.append((db.playerID, getMessagesLastID(db.playerID)))
    for galaxyID in getPlayer().galaxies:
        mailboxes.append((galaxyID, getMessagesLastID(galaxyID)))
    mailboxes.append((OID_UNIVERSE, getMessagesLastID(OID_UNIVERSE)))
    # get data
    data = cmdProxy.multiGetMsgs(OID_UNIVERSE, mailboxes)
    # process
    new = 0
    now = time.time()
    for objID, messages in data:
        obj = get(objID)
        # add new
        for message in messages:
            #@log.debug("Got message ID", message["id"])
            if message["id"] not in obj._messages:
                if message["forum"] != "OUTBOX":
                    message["readed"] = 0
                    message["replied"] = 0
                else:
                    message["readed"] = 1
                    message["replied"] = 0
                obj._messagesLastID = max(message["id"], obj._messagesLastID)
                obj._messages[message["id"]] = message
                new += 1
            else:
                log.warning("Got duplicated message", message)
    if new > 0:
        callbackObj.onNewMessages(new)
    return new
Пример #4
0
def getMsgText(msgID, data):
	msg, transform, severity = msgData.get(msgID, (None, None, None))
	# create default messages
	if not msg:
		return _('ERROR\nMissing text for msg %d: %s') % (msgID, repr(data))
	# there is message text -> create message
	# force unicode
	msg = _(msg)
	if data == None:
		return msg
	try:
		# tranform data
		newData = {}
		if not (type(data) == types.ListType or type(data) == types.TupleType):
			data = (data,)
		if transform:
			index = 1
			for tranFunc in transform:
				newData[str(index)] = tranFunc(data[index - 1])
				index += 1
		else:
			index = 1
			for item in data:
				newData[str(index)] = item
				index += 1
		text = msg % newData
	except Exception, e:
		# wrong arguments -> default message
		log.warning("Error while formating message")
		return _('ERROR\nWrong format for msg %d: %s\nException: %s: %s\nFormat: %s') % (msgID, repr(data), str(e.__class__), str(e), msg)
Пример #5
0
 def update(self, tran, obj):
     if obj.impactDelay > Rules.asteroidImpactDelay:
         # delete me
         self.cmd(obj).disbandFleet(tran, obj)
         return
     # closest system
     if not hasattr(obj, "closeSystem") or not tran.db.has_key(obj.closeSystem):
         if obj.orbiting == OID_NONE:
             log.warning("No close system for asteroid", obj.oid)
             # select any system
             systemID = tran.db[tran.db[OID_UNIVERSE].galaxies[0]].systems[0]
             obj.closeSystem = systemID
         else:
             obj.closeSystem = obj.orbiting
             system = tran.db[obj.closeSystem]
             if system.type == T_SYSTEM:
                 if obj.oid not in system.closeFleets:
                     system.closeFleets.append(obj.oid)
             else:
                 log.debug("IAsteroid - invalid orbiting", obj.orbiting)
                 self.cmd(obj).disbandFleet(tran, obj)
                 return
     # verify close system
     if tran.db.has_key(obj.closeSystem):
         system = tran.db[obj.closeSystem]
         if system.type == T_SYSTEM:
             if obj.oid not in system.closeFleets:
                 #@log.debug("Adding fleet", obj.oid, "into closeFleets", system.oid)
                 system.closeFleets.append(obj.oid)
         else:
             obj.closeSystem = OID_NONE
     else:
         obj.closeSystem = OID_NONE
Пример #6
0
def getMsgText(msgID, data):
    msg, transform, severity = msgData.get(msgID, (None, None, None))
    # create default messages
    if not msg:
        return _('ERROR\nMissing text for msg %d: %s') % (msgID, repr(data))
    # there is message text -> create message
    # force unicode
    msg = _(msg)
    if data == None:
        return msg
    try:
        # tranform data
        newData = {}
        if not (type(data) == types.ListType or type(data) == types.TupleType):
            data = (data, )
        if transform:
            index = 1
            for tranFunc in transform:
                newData[str(index)] = tranFunc(data[index - 1])
                index += 1
        else:
            index = 1
            for item in data:
                newData[str(index)] = item
                index += 1
        text = msg % newData
    except Exception, e:
        # wrong arguments -> default message
        log.warning("Erorr while formating message")
        return _(
            'ERROR\nWrong format for msg %d: %s\nException: %s: %s\nFormat: %s'
        ) % (msgID, repr(data), str(e.__class__), str(e), msg)
Пример #7
0
 def recordScanLevel(self, tran, obj, scanPwr, player, contactType):
     if obj.owner == player.oid:
         log.warning("Scan on own asteroid!", obj.oid)
         return
     if scanPwr >= Rules.level1InfoScanPwr:
         self.cmd(player).addObjectToMap(tran, player, obj, scanPwr,
                                         Const.CONTACT_NONE)
Пример #8
0
def playMusic():
    if musicEnabled:
        try:
            if pygame.mixer.music.get_busy() == False:
                pygame.mixer.music.play(-1)
        except pygame.error:
            log.warning("Cannot play music")
Пример #9
0
 def __call__(self, *args):
     if self.client.msgHandler:
         self.client.msgHandler(MSG_CMD_BEGIN, None)
     # retry 'turn in progress' and server restart situations
     retries = 10
     ok = 0
     while retries > 0:
         try:
             result = self.processCall(args)
             ok = 1
             break
         except ServerStatusException as e:
             log.warning("Cannot complete request - retrying...")
             retries -= 1
             time.sleep(1)
         # this was commented out
         except Exception as e:
             log.warning("Cannot complete request")
             if self.client.msgHandler:
                 self.client.msgHandler(MSG_CMD_END, None)
             raise e
     if self.client.msgHandler:
         self.client.msgHandler(MSG_CMD_END, None)
     if ok:
         return result
     else:
         raise IClientException('Cannot send request to the server')
Пример #10
0
 def update(self, tran, obj):
     if obj.impactDelay > Rules.asteroidImpactDelay:
         # delete me
         self.cmd(obj).disbandFleet(tran, obj)
         return
     # closest system
     if not hasattr(obj, "closeSystem") or not tran.db.has_key(
             obj.closeSystem):
         if obj.orbiting == Const.OID_NONE:
             log.warning("No close system for asteroid", obj.oid)
             # select any system
             systemID = tran.db[tran.db[
                 Const.OID_UNIVERSE].galaxies[0]].systems[0]
             obj.closeSystem = systemID
         else:
             obj.closeSystem = obj.orbiting
             system = tran.db[obj.closeSystem]
             if system.type == Const.T_SYSTEM:
                 if obj.oid not in system.closeFleets:
                     system.closeFleets.append(obj.oid)
             else:
                 log.debug("IAsteroid - invalid orbiting", obj.orbiting)
                 self.cmd(obj).disbandFleet(tran, obj)
                 return
     # verify close system
     if tran.db.has_key(obj.closeSystem):
         system = tran.db[obj.closeSystem]
         if system.type == Const.T_SYSTEM:
             if obj.oid not in system.closeFleets:
                 #@log.debug("Adding fleet", obj.oid, "into closeFleets", system.oid)
                 system.closeFleets.append(obj.oid)
         else:
             obj.closeSystem = Const.OID_NONE
     else:
         obj.closeSystem = Const.OID_NONE
Пример #11
0
def getMessages():
	# construct list of mailboxes
	mailboxes = []
	mailboxes.append((db.playerID, getMessagesLastID(db.playerID)))
	for galaxyID in getPlayer().galaxies:
		mailboxes.append((galaxyID, getMessagesLastID(galaxyID)))
	mailboxes.append((OID_UNIVERSE, getMessagesLastID(OID_UNIVERSE)))
	# get data
	data = cmdProxy.multiGetMsgs(OID_UNIVERSE, mailboxes)
	# process
	new = 0
	now = time.time()
	for objID, messages in data:
		obj = get(objID)
		# add new
		for message in messages:
			#@log.debug("Got message ID", message["id"])
			if message["id"] not in obj._messages:
				if message["forum"] != "OUTBOX":
					message["readed"] = 0
					message["replied"] = 0
				else:
					message["readed"] = 1
					message["replied"] = 0
				obj._messagesLastID = max(message["id"], obj._messagesLastID)
				obj._messages[message["id"]] = message
				new += 1
			else:
				log.warning("Got duplicated message", message)
	if new > 0:
		callbackObj.onNewMessages(new)
	return new
Пример #12
0
def playMusic():
	if musicEnabled:
		try:
			if pygame.mixer.music.get_busy() == False:
				pygame.mixer.music.play(-1)
		except pygame.error:
			log.warning("Cannot play music")
Пример #13
0
 def processINITPhase(self, tran, obj, data):
     try:
         ## find active/inactive pacts
         # set all active/on pacts to active
         for playerID in obj.players:
             #@log.debug("Processing player", playerID)
             player = tran.db[playerID]
             for partyID in player.diplomacyRels:
                 #@log.debug("Processing party", partyID)
                 dipl = player.diplomacyRels[partyID]
                 for pactID in dipl.pacts.keys():
                     if pactID not in Rules.pactDescrs:
                         # this is invalid pactID
                         log.debug(playerID, "Deleting invalid pact with", partyID, "pact", pactID)
                         del dipl.pacts[pactID]
                         continue
                     if dipl.pacts[pactID][0] > PACT_OFF:
                         dipl.pacts[pactID][0] = PACT_ACTIVE
         # inactivate all pact that does not satisfy conditions
         changed = 1
         defaultPact = [PACT_OFF]
         while changed:
             changed = 0
             log.debug("Inactivate pacts iteration starting...")
             for playerID in obj.players:
                 #@log.debug("Processing player", playerID)
                 player = tran.db[playerID]
                 # all parties of a player
                 for partyID in player.diplomacyRels:
                     #@log.debug("Processing party", partyID)
                     party = tran.db[partyID]
                     partyDipl = party.diplomacyRels.get(playerID, None)
                     if not partyDipl:
                         continue
                     dipl = player.diplomacyRels[partyID]
                     # correct relations
                     dipl.relation = min(dipl.relation, partyDipl.relation)
                     # all pacts with party
                     for pactID in dipl.pacts:
                         # check validity interval
                         pactSpec = Rules.pactDescrs[pactID]
                         if (dipl.relation < pactSpec.validityInterval[0] or \
                             dipl.relation > pactSpec.validityInterval[1]) and \
                             dipl.pacts[pactID][0] == PACT_ACTIVE:
                             #@log.debug("Inactivating pact (validity interval)", playerID, pactID)
                             dipl.pacts[pactID][0] = PACT_INACTIVE
                             changed = 1
                         # check conditions for the pact if pact is active
                         if dipl.pacts[pactID][0] == PACT_ACTIVE:
                             for condPactID in dipl.pacts[pactID][1:]:
                                 #@log.debug("Checking", playerID, pactID, "against", partyID, condPactID)
                                 if partyDipl and partyDipl.pacts.get(condPactID, defaultPact)[0] != PACT_ACTIVE:
                                     dipl.pacts[pactID][0] = PACT_INACTIVE
                                     changed = 1
     except Exception:
         log.warning("Cannot process diplomacy initialization")
     # TODO - send notifications if pacts are changed
     # remove old messages
     self.cmd(obj).deleteOldMsgs(tran, obj)
     return obj.players[:] + [OID_NATURE]
Пример #14
0
	def moveToWormhole(self, tran, obj, targetID):
                origin = tran.db[targetID]
                if not (obj.x==origin.x and obj.y==origin.y):
			if not self.cmd(obj).moveToTarget(tran, obj, targetID):
				return 0 #ship hasn't arrived
		# enter wormhole
                if origin.type == T_WORMHOLE: #is wormhole, now enter it!
			destinationWormHole = tran.db[origin.destinationOid]
			if destinationWormHole.oid == targetID:
				return 1
			if obj.oid not in destinationWormHole.fleets:
				destinationWormHole.fleets.append(obj.oid)
			if obj.oid not in destinationWormHole.closeFleets:
				destinationWormHole.closeFleets.append(obj.oid)
			if obj.oid in origin.fleets:
				origin.fleets.remove(obj.oid)
			if obj.oid in origin.closeFleets:
				origin.closeFleets.remove(obj.oid)
			obj.closeSystem = destinationWormHole.oid
                        log.debug('IFleet', 'Entering Wormhole - destination ', destinationWormHole.oid)
			obj.orbiting = destinationWormHole.oid
			obj.x = destinationWormHole.x
			obj.y = destinationWormHole.y
			destinationWormHole.scannerPwrs[obj.owner] = max(obj.scannerPwr, destinationWormHole.scannerPwrs.get(obj.owner, 0))
                        Utils.sendMessage(tran, obj, MSG_ENTERED_WORMHOLE, destinationWormHole.oid , (origin.name,destinationWormHole.name))
			arrived = 1
		else: #is not wormhole...how'd you ever execute this command? Or is there some weird "terraform wormhole" technology we never forsaw?
                        log.warning('IFleet', 'Cannot enter non-existant wormhole at location ', origin.oid)
                        #Utils.sendMessage(tran, obj, MSG_ENTERED_WORMHOLE, destinationWormHole.oid , (origin.name,destinationWormHole.name))
                        arrived = 1 #since the move part was successful, just ignore this problem for the player
                return arrived
Пример #15
0
def stopMusic():
	try:
		if pygame.mixer.music.get_busy() == True:
			 pygame.mixer.music.fadeout(1000)
	except pygame.error:
		log.warning("Cannot stop music")
	except error:
		pass
Пример #16
0
def stopMusic():
    try:
        if pygame.mixer.music.get_busy() == True:
             pygame.mixer.music.fadeout(1000)
    except pygame.error:
        log.warning("Cannot stop music")
    except error:
        pass
Пример #17
0
 def verifyPassword(self, login, password):
     """Called by Authentication module, returns 0 if password is valid"""
     try:
         return self.rpc.ospace.verify_user(login, password)
     except xmlrpclib.Fault, f:
         if f.faultString == "Bad login/pass combination.":
             return False
         log.warning("Cannot complete Wordpress XML-RPC call")
Пример #18
0
 def getObjectsInSpace(self, tran, obj):
     inSpace = obj.closeFleets[:]
     for fleetID in obj.fleets:
         try:
             inSpace.remove(fleetID)
         except ValueError:
             log.warning(obj.oid, "Cannot remove fleet from closeFleets", fleetID, obj.fleets, obj.closeFleets)
     return inSpace
Пример #19
0
 def getObjectsInSpace(self, tran, obj):
     inSpace = obj.closeFleets[:]
     for fleetID in obj.fleets:
         try:
             inSpace.remove(fleetID)
         except ValueError:
             log.warning(obj.oid, "Cannot remove fleet from closeFleets", fleetID, obj.fleets, obj.closeFleets)
     return inSpace
Пример #20
0
def onUpdateFinished():
    global progressDlg
    log.debug("onUpdateFinished")
    try:
        progressDlg.Close()
        progressDlg.Destroy()
        progressDlg = None
    except:
        log.warning("Cannot close ProgressDialog window")
Пример #21
0
def onUpdateFinished():
    global progressDlg
    log.debug("onUpdateFinished")
    try:
        progressDlg.hide()
    except:
        log.warning("Cannot delete progressDlg window")
    for dialog in gdata.updateDlgs:
        dialog.update()
Пример #22
0
def onUpdateFinished():
	global progressDlg
	log.debug("onUpdateFinished")
	try:
		progressDlg.Close()
		progressDlg.Destroy()
		progressDlg = None
	except:
		log.warning("Cannot close ProgressDialog window")
Пример #23
0
def setMusicVolume(volume):
	global musicVolume 
	global musicEnabled
	musicVolume = volume
	try:
		if musicEnabled :
			pygame.mixer.music.set_volume(volume)
	except:
		log.warning("Cannot set music volume")
Пример #24
0
def setMusicVolume(volume):
    global musicVolume
    global musicEnabled
    musicVolume = volume
    try:
        if musicEnabled :
            pygame.mixer.music.set_volume(volume)
    except:
        log.warning("Cannot set music volume")
Пример #25
0
def onUpdateFinished():
	global progressDlg
	log.debug("onUpdateFinished")
	try:
		progressDlg.hide()
	except:
		log.warning("Cannot delete progressDlg window")
	for dialog in gdata.updateDlgs:
		dialog.update()
Пример #26
0
def updateDatabase(clearDB=0):
    try:
        return updateDatabaseUnsafe(clearDB)
    except:
        log.warning("Cannot update database")
    # again with clear
    callbackObj.onUpdateFinished()
    messageEnable(SMESSAGE_NEWTURN)
    messageEnable(SMESSAGE_NEWMESSAGE)
    return updateDatabaseUnsafe(clearDB=1, force=1)
Пример #27
0
def playSound(style):
    if soundEnabled and style in sounds:
        try:
            if sounds[style]["sound"] == None:
                filename = sounds[style]["fname"]
                sounds[style]["sound"] = pygame.mixer.Sound(filename)
            sounds[style]["sound"].set_volume(soundVolume)
            sounds[style]["sound"].play()
        except pygame.error:
            log.warning("Cannot play sound", style)
Пример #28
0
def playSound(style):
	if soundEnabled and style in sounds:
		try:
			if sounds[style]["sound"] == None:
				filename = sounds[style]["fname"]
				sounds[style]["sound"] = pygame.mixer.Sound(filename)
			sounds[style]["sound"].set_volume(soundVolume)
			sounds[style]["sound"].play()
		except pygame.error:
			log.warning("Cannot play sound", style)
Пример #29
0
def updateDatabase(clearDB = 0):
    try:
        return updateDatabaseUnsafe(clearDB)
    except:
        log.warning("Cannot update database")
    # again with clear
    callbackObj.onUpdateFinished()
    messageEnable(Const.SMESSAGE_NEWTURN)
    messageEnable(Const.SMESSAGE_NEWMESSAGE)
    return updateDatabaseUnsafe(clearDB = 1, force = 1)
Пример #30
0
	def removePlayer(self, playerID):
		log.debug('removePlayer', playerID)
		player = self.db[playerID]
		# unregister player
		self.unregisterPlayer(player)
		# remove player from universe
		universe = self.db[OID_UNIVERSE]
		try:
			universe.players.remove(playerID)
		except ValueError:
			log.warning("Cannot remove player", playerID)
Пример #31
0
	def update(self, tran, obj):
		# clean up negative build queues and fix missing demolishStruct keys
		loopAgain = True
		while loopAgain:
			deletedKey = False
			for key in range(0,len(obj.prodQueue)):
				item = obj.prodQueue[key]
				if not hasattr(item, "demolishStruct"):
					item.demolishStruct = OID_NONE
				if item.quantity < 0:
					log.warning("Deleting negative item queue on", obj.oid,"for player",obj.owner)
					if item.isShip:
						tech = player.shipDesigns[item.techID]
					else:
						tech = Rules.techs[item.techID]
					player = tran.db[obj.owner]
					for sr in tech.buildSRes:
						player.stratRes[sr] = player.stratRes.get(sr, 0) + item.quantity #quantity negative, so subtracting strat resources
					# del the bad item. Since this changes indicies, start the check over again on remaining items
					deletedKey = True
					del obj.prodQueue[key]
					break
			# no more bad entries found; break the while loop
			if not deletedKey:
				loopAgain = False
				
		# TODO: remove in 0.5.34
		for struct in obj.slots:
			if len(struct) < 4:
				# add oper status
				struct.append(100)
		# change owner to OID_NONE when owner is invalid
		if obj.owner != OID_NONE:
			player = tran.db.get(obj.owner, None)
			if not player or player.type not in PLAYER_TYPES or obj.oid not in player.planets:
				# TODO this can be a probem - this planet cannot be attacked!
				log.warning("Changing owner to OID_NONE - invalid owner", obj)
				self.cmd(obj).changeOwner(tran, obj, OID_NONE, force = 1)
				# kill all population
				obj.storPop = 0
				return
		# TODO: remove in 0.5.65
		obj.storBio = int(obj.storBio)
		obj.storEn = int(obj.storEn)
		# TODO: remove in 0.5.69
		if not hasattr(obj, "globalQueue"):
			obj.globalQueue = 0
		# check compOf
		if not tran.db.has_key(obj.compOf) or tran.db[obj.compOf].type != T_SYSTEM:
			log.debug("CONSISTENCY invalid compOf for planet", obj.oid)
		# fix signature
		obj.signature = 75
		if not hasattr(obj, 'moraleModifiers'):
			obj.moraleModifiers = [ 0.0 , 0.0 , 0.0 , 0.0 ]	
Пример #32
0
 def removePlayer(self, playerID):
     log.debug('removePlayer', playerID)
     player = self.db[playerID]
     # unregister player
     self.unregisterPlayer(player)
     # remove player from universe
     universe = self.db[Const.OID_UNIVERSE]
     try:
         universe.players.remove(playerID)
     except ValueError:
         log.warning("Cannot remove player", playerID)
Пример #33
0
 def login(self, gameID, login, password):
     self.gameID = gameID.encode("ascii")
     # hash password with challenge
     passwd = ige.Authentication.encode(password, self.challenge)
     #@log.debug(login, password, passwd)
     try:
         IProxy('login', None, self)(login, passwd, self.hostID)
     except:
         log.warning('login failed')
         return 0
     log.debug('login succeeded')
     self.logged = 1
     return 1
Пример #34
0
 def login(self, gameID, login, password):
     self.gameID = gameID.encode("ascii")
     # hash password with challenge
     passwd = ige.Authentication.encode(password, self.challenge)
     #@log.debug(login, password, passwd)
     try:
         IProxy('login', None, self)(login, passwd, self.hostID)
     except:
         log.warning('login failed')
         return 0
     log.debug('login succeeded')
     self.logged = 1
     return 1
Пример #35
0
def createSounds(section, option):
	global sounds
	name = "%s-%s" % (section[:-4], option[6:])
	filename = os.path.join(skinDir, config.get(section, option))
	try:
		sounds[name] = {}
		sounds[name]["fname"] = filename
		if soundEnabled:
			sounds[name]["sound"] = pygame.mixer.Sound(filename)
		else:
			sounds[name]["sound"] = None
	except pygame.error:
		log.warning("Cannot create sound", name, filename)
Пример #36
0
def createSounds(section, option):
    global sounds
    name = "%s-%s" % (section[:-4], option[6:])
    filename = os.path.join(skinDir, config.get(section, option))
    try:
        sounds[name] = {}
        sounds[name]["fname"] = filename
        if soundEnabled:
            sounds[name]["sound"] = pygame.mixer.Sound(filename)
        else:
            sounds[name]["sound"] = None
    except pygame.error:
        log.warning("Cannot create sound", name, filename)
Пример #37
0
	def login(self, gameID, login, password):
		self.gameID = gameID.encode("ascii")
		# hash password with challenge
		passwd = md5.new(password + self.challenge).hexdigest()
		#@log.debug(login, password, passwd)
		try:
			apply(IProxy('login', None, self), (login, passwd, self.hostID))
		except:
			log.warning('login failed')
			return 0
		log.debug('login succeeded')
		self.logged = 1
		return 1
Пример #38
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
Пример #39
0
	def delete(self, tran, obj):
		log.debug("Deleting player", obj.oid)
		# delete relations
		for playerID in tran.db[OID_UNIVERSE].players:
			player = tran.db[playerID]
			self.cmd(player).deleteDiplomacyWith(tran, player, obj.oid)
		# delete fleets
		for fleetID in obj.fleets:
			fleet = tran.db[fleetID]
			self.cmd(fleet).disbandFleet(tran, fleet)
		try:
			tran.gameMngr.removePlayer(obj.oid)
		except Exception:
			log.warning("Cannot remove player")
Пример #40
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")
Пример #41
0
 def login(self, gameID, login, password):
     self.gameID = gameID.encode("ascii")
     # hash password with challenge
     passwd = hashlib.sha512(
         hashlib.sha512(password).hexdigest() + self.challenge).hexdigest()
     #@log.debug(login, password, passwd)
     try:
         apply(IProxy('login', None, self), (login, passwd, self.hostID))
     except:
         log.warning('login failed')
         return 0
     log.debug('login succeeded')
     self.logged = 1
     return 1
Пример #42
0
 def processFINALPhase(self, tran, obj, data):
     if not Rules.Tech.PIRATEBREWERY in obj.techs:
         log.warning('Adding new pirate structures to human pirate player.')
         self.cmd(obj).update(tran, obj) #grant the techs because something screwed up
     obj.govPwr = Rules.pirateGovPwr
     IPlayer.processFINALPhase(self, tran, obj, data)
     # get fame every 1:00 turns
     if tran.db[Const.OID_UNIVERSE].turn % Rules.turnsPerDay == 0:
         Utils.sendMessage(tran, obj, Const.MSG_GAINED_FAME, obj.oid, Rules.pirateSurvivalFame)
         obj.pirateFame += Rules.pirateSurvivalFame
     # fix goverment power
     obj.govPwrCtrlRange = 10000
     # bonus for gained fame
     obj.prodEff += obj.pirateFame / 100.0
Пример #43
0
def loadMusic(file):
    if musicEnabled and pygame.mixer.music.get_busy() == False:
        global themeMusic
        if file != None:
            musicFile = "res.ext/music/" + file
        elif themeMusic != None:
            musicFile = "res.ext/music/" + themeMusic
        else:
            musicFile = "res.ext/music/riddleofsteel.ogg"
        if os.path.exists(musicFile):
            try:
                pygame.mixer.music.load(musicFile)
            except pygame.error:
                log.warning("Cannot load music ",musicFile)
Пример #44
0
	def connect(self, login):
		# to enable sending commands
		self.connected = 1
		# create connection
		log.debug('Connecting to the server', self.server)
		# send hello message
		log.debug('Sending hello')
		try:
			self.sid, self.challenge = self.hello(login, self.clientIdent)
		except:
			log.warning('Cannot connect to the server.')
			self.connected = 0
			raise IClientException('Cannot connect to the server.')
		log.debug(self.sid, self.challenge)
Пример #45
0
 def connect(self):
     # to enable sending commands
     self.connected = 1
     # create connection
     log.debug('Connecting to the server', self.server)
     # send hello message
     log.debug('Sending hello')
     try:
         self.sid, self.challenge = self.hello(self.clientIdent)
     except:
         log.warning('Cannot connect to the server.')
         self.connected = 0
         raise IClientException('Cannot connect to the server.')
     log.debug(self.sid, self.challenge)
Пример #46
0
	def delete(self, tran, obj):
		log.debug("Deleting player", obj.oid)
		# delete relations
		for playerID in tran.db[OID_UNIVERSE].players:
			player = tran.db[playerID]
			self.cmd(player).deleteDiplomacyWith(tran, player, obj.oid)
		# delete fleets
		for fleetID in obj.fleets:
			fleet = tran.db[fleetID]
			self.cmd(fleet).disbandFleet(tran, fleet)
		try:
			tran.gameMngr.removePlayer(obj.oid)
		except Exception:
			log.warning("Cannot remove player")
Пример #47
0
def loadMusic(file):
	if musicEnabled and pygame.mixer.music.get_busy() == False:
		global themeMusic
		if file != None:
			musicFile = "res.ext/music/" + file
		elif themeMusic != None:
			musicFile = "res.ext/music/" + themeMusic
		else:
			musicFile = "res.ext/music/riddleofsteel.ogg"
		if os.path.exists(musicFile):
			try:
				pygame.mixer.music.load(musicFile)
			except pygame.error:
				log.warning("Cannot load music ",musicFile)
Пример #48
0
	def disbandFleet(self, tran, obj):
		log.debug('IFleet', 'disbanding fleet', obj.oid, 'of player', obj.owner)
		# remove from player's fleets
		try:
			if obj.owner != OID_NONE:
				tran.db[obj.owner].fleets.remove(obj.oid)
		except Exception:
			log.warning('IFleet', 'disbandFleet: cannot remove fleet from owner\'s fleet')
			pass
		# remove from orbit
		# remove from index if necessary
		if obj.orbiting != OID_NONE:
			try:
				if tran.db.has_key(obj.orbiting):
					tran.db[obj.orbiting].fleets.remove(obj.oid)
			except Exception:
				log.warning('IFleet', 'disbandFleet: cannot remove fleet from system.')
				pass
		# remove from close fleets
		if obj.closeSystem != OID_NONE:
			try:
				if tran.db.has_key(obj.closeSystem):
					tran.db[obj.closeSystem].closeFleets.remove(obj.oid)
			except Exception:
				log.warning("IFleet", "disbandFleet: cannot remove fleet from the close system.")
		# delete from database
		try:
			tran.db.delete(obj.oid)
		except KeyError:
			log.warning('IFleet', 'disbandFleet: cannot remove fleet from database.')
Пример #49
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")
Пример #50
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
Пример #51
0
 def processFINALPhase(self, tran, obj, data):
     if not Rules.Tech.PIRATEBREWERY in obj.techs:
         log.warning('Adding new pirate structures to human pirate player.')
         self.cmd(obj).update(
             tran, obj)  #grant the techs because something screwed up
     obj.govPwr = Rules.pirateGovPwr
     IPlayer.processFINALPhase(self, tran, obj, data)
     # get fame every 1:00 turns
     if tran.db[Const.OID_UNIVERSE].turn % Rules.turnsPerDay == 0:
         Utils.sendMessage(tran, obj, Const.MSG_GAINED_FAME, obj.oid,
                           Rules.pirateSurvivalFame)
         obj.pirateFame += Rules.pirateSurvivalFame
     # fix goverment power
     obj.govPwrCtrlRange = 10000
     # bonus for gained fame
     obj.prodEff += obj.pirateFame / 100.0
Пример #52
0
def setDefaults(gdata, options):
    if gdata.config.client.language == None:
        gdata.config.client.language = 'en'
    if gdata.config.defaults.minfleetsymbolsize == None:
        gdata.config.defaults.minfleetsymbolsize = 4
    if gdata.config.defaults.minplanetsymbolsize == None:
        gdata.config.defaults.minplanetsymbolsize = 5
    if gdata.config.defaults.maxfleetsymbolsize == None:
        gdata.config.defaults.maxfleetsymbolsize = 0
    if gdata.config.defaults.maxplanetsymbolsize == None:
        gdata.config.defaults.maxplanetsymbolsize = 0
    if gdata.config.game.screenshot_dir is None:
        gdata.config.game.screenshot_dir = os.path.join(
            options.configDir, 'screenshots')
        try:
            os.makedirs(gdata.config.game.screenshot_dir)
        except OSError:
            pass
    # read Highlights
    if gdata.config.defaults.colors != None:
        for coldef in gdata.config.defaults.colors.split(' '):
            m = re.match('(\d+):(0[xX].*?),(0[xX].*?),(0[xX].*)', coldef)
            if m != None:
                id = int(m.group(1))
                red = min(int(m.group(2), 16), 255)
                green = min(int(m.group(3), 16), 255)
                blue = min(int(m.group(4), 16), 255)
                gdata.playersHighlightColors[id] = (red, green, blue)
            else:
                log.warning('OSCI', 'Unrecognized highlight definition :',
                            coldef)
    # read Object Keys
    if gdata.config.defaults.objectkeys != None:
        for objectkey in gdata.config.defaults.objectkeys.split(' '):
            m = re.match('(\d+):(\d+)', objectkey)
            if m != None:
                key = int(m.group(1))
                objid = int(m.group(2))
                gdata.objectFocus[key] = objid
            else:
                log.warning('OSCI', 'Unrecognized object key definition :',
                            objectkey)
Пример #53
0
	def delete(self, tran, obj):
		# check whether it is AI or normal player
		if obj.type in AI_PLAYER_TYPES:
			# remove AI account from the game, and record in the AI list
			log.debug("Removing AI account from the AI list", obj.oid)
			tran.gameMngr.clientMngr.removeAiAccount(obj.login)
			aiList = AIList(tran.gameMngr.configDir)
			aiList.remove(obj.login)
		log.debug("Deleting player", obj.oid)
		# delete relations
		for playerID in tran.db[OID_UNIVERSE].players:
			player = tran.db[playerID]
			self.cmd(player).deleteDiplomacyWith(tran, player, obj.oid)
		# delete fleets
		for fleetID in obj.fleets:
			fleet = tran.db[fleetID]
			self.cmd(fleet).disbandFleet(tran, fleet)
		try:
			tran.gameMngr.removePlayer(obj.oid)
		except Exception:
			log.warning("Cannot remove player")
Пример #54
0
	def __call__(self, *args):
		if self.client.msgHandler:
			apply(self.client.msgHandler, (MSG_CMD_BEGIN, None))
		# retry 'turn in progress' and server restart situations
		retries = 10
		ok = 0
		while retries > 0:
			try:
				result = self.processCall(args)
				ok = 1
				break
			except ServerStatusException, e:
				log.warning("Cannot complete request - retrying...")
				retries -= 1
				time.sleep(1)
			# this was commented out
			except Exception, e:
				log.warning("Cannot complete request")
				if self.client.msgHandler:
					apply(self.client.msgHandler, (MSG_CMD_END, None))
				raise e
Пример #55
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
Пример #56
0
def getMessages():
    # construct list of mailboxes
    mailboxes = []
    mailboxes.append((db.playerID, getMessagesLastID(db.playerID)))
    galaxyID = getPlayer().galaxy
    if galaxyID:
        mailboxes.append((galaxyID, getMessagesLastID(galaxyID)))
    mailboxes.append(
        (Const.OID_UNIVERSE, getMessagesLastID(Const.OID_UNIVERSE)))
    # get data
    data = cmdProxy.multiGetMsgs(Const.OID_UNIVERSE, mailboxes)
    # process
    new = 0
    now = time.time()
    for objID, messages in data:
        obj = get(objID)
        # delete old messages TODO leave this to the user
        #for messageID in obj._messages.keys():
        #    message = obj._messages[messageID]
        #    if message["time"] + Rules.messageTimeout < now:
        #        del obj._messages[messageID]
        # add new
        for message in messages:
            #@log.debug("Got message ID", message["id"])
            if message["id"] not in obj._messages:
                if message["forum"] != "OUTBOX":
                    message["readed"] = 0
                    message["replied"] = 0
                else:
                    message["readed"] = 1
                    message["replied"] = 0
                obj._messagesLastID = max(message["id"], obj._messagesLastID)
                obj._messages[message["id"]] = message
                new += 1
            else:
                log.warning("Got duplicated message", message)
    if new > 0:
        callbackObj.onNewMessages(new)
    return new
Пример #57
0
 def processINITPhase(self, tran, obj, data):
     for galaxyID in obj.galaxies:
         galaxy = tran.db[galaxyID]
         self.cmd(galaxy).enableTime(tran, galaxy)
     try:
         ## find active/inactive pacts
         # set all active/on pacts to active
         for playerID in obj.players:
             #@log.debug("Processing player", playerID)
             player = tran.db[playerID]
             for partyID in player.diplomacyRels:
                 #@log.debug("Processing party", partyID)
                 dipl = player.diplomacyRels[partyID]
                 for pactID in dipl.pacts.keys():
                     if pactID not in Rules.pactDescrs:
                         # this is invalid pactID
                         log.debug(playerID, "Deleting invalid pact with", partyID, "pact", pactID)
                         del dipl.pacts[pactID]
                         continue
                     if dipl.pacts[pactID][0] > Const.PACT_OFF:
                         dipl.pacts[pactID][0] = Const.PACT_ACTIVE
         # inactivate all pact that does not satisfy conditions
         changed = 1
         defaultPact = [Const.PACT_OFF]
         while changed:
             changed = 0
             log.debug("Inactivate pacts iteration starting...")
             for playerID in obj.players:
                 #@log.debug("Processing player", playerID)
                 player = tran.db[playerID]
                 # all parties of a player
                 for partyID in player.diplomacyRels:
                     #@log.debug("Processing party", partyID)
                     party = tran.db[partyID]
                     partyDipl = party.diplomacyRels.get(playerID, None)
                     if not partyDipl:
                         continue
                     dipl = player.diplomacyRels[partyID]
                     # correct relations
                     dipl.relation = min(dipl.relation, partyDipl.relation)
                     # all pacts with party
                     for pactID in dipl.pacts:
                         # check validity interval
                         pactSpec = Rules.pactDescrs[pactID]
                         if (dipl.relation < pactSpec.validityInterval[0] or \
                             dipl.relation > pactSpec.validityInterval[1]) and \
                             dipl.pacts[pactID][0] == Const.PACT_ACTIVE:
                             #@log.debug("Inactivating pact (validity interval)", playerID, pactID)
                             dipl.pacts[pactID][0] = Const.PACT_INACTIVE
                             changed = 1
                         # check conditions for the pact if pact is active
                         if dipl.pacts[pactID][0] == Const.PACT_ACTIVE:
                             for condPactID in dipl.pacts[pactID][1:]:
                                 #@log.debug("Checking", playerID, pactID, "against", partyID, condPactID)
                                 if partyDipl and partyDipl.pacts.get(condPactID, defaultPact)[0] != Const.PACT_ACTIVE:
                                     dipl.pacts[pactID][0] = Const.PACT_INACTIVE
                                     changed = 1
     except Exception:
         log.warning("Cannot process diplomacy initialization")
     # TODO - send notifications if pacts are changed
     # remove old messages
     self.cmd(obj).deleteOldMsgs(tran, obj)
     return obj.players[:] + [Const.OID_NATURE]
Пример #58
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