def act_selectRace(data): user = dbi.getXbyY('User', 'sid', data['sid']) if user.currentTokenBadge: raise BadFieldException('badStage') game = user.game if not (game and user.inGame): raise BadFieldException('notInGame') checkStage(GAME_SELECT_RACE, user) if (user.game.state == misc.GAME_START): user.game.state = misc.GAME_PROCESSING chosenBadge = game.getTokenBadge(data['position']) position = chosenBadge.pos tokenBadges = dbi.query(TokenBadge).order_by(TokenBadge.pos).all() tokenBadges = tokenBadges[:6] price = position if user.coins < price: raise BadFieldException('badMoneyAmount') raceId, specialPowerId = chosenBadge.raceId, chosenBadge.specPowId addUnits = callRaceMethod(raceId, 'turnStartReinforcements') tokensNum = races.racesList[raceId].initialNum + races.specialPowerList[ specialPowerId].tokensNum user.coins += chosenBadge.bonusMoney - price user.currentTokenBadge = chosenBadge user.tokensInHand = tokensNum + addUnits chosenBadge.inDecline = False chosenBadge.bonusMoney = 0 chosenBadge.totalTokensNum = tokensNum + addUnits chosenBadge.specPowNum = races.specialPowerList[specialPowerId].bonusNum chosenBadge.pos = None dbi.flush(chosenBadge) updateRacesOnDesk(game, position) dbi.updateHistory(user, GAME_SELECT_RACE, chosenBadge.id) dbi.updateGameHistory(game, data) return {'result': 'ok', 'tokenBadgeId': chosenBadge.id}
def act_aiJoin(data): game = dbi.getXbyY('Game', 'id', data['gameId']) if game.state != GAME_WAITING: raise BadFieldException('badGameState') maxPlayersNum = game.map.playersNum if len(game.players) >= maxPlayersNum: raise BadFieldException('tooManyPlayers') maxPriority = max(game.players, key=lambda x: x.priority).priority if len( game.players) else 0 aiCnt = len(filter(lambda x: x.isAI == True, game.players)) sid = getSid() ai = User('AI%d' % sid, None, True) ai.sid = sid ai.gameId = game.id ai.isReady = True ai.priority = maxPriority + 1 ai.inGame = True dbi.add(ai) dbi.flush(ai) game.aiRequiredNum -= 1 readyPlayersNum = dbi.query(User).filter(User.gameId == game.id).filter( User.isReady == True).count() if maxPlayersNum == readyPlayersNum: misc_game.startGame(game, ai, data) return {'result': 'ok', 'sid': ai.sid, 'id': ai.id}
def act_uploadMap(data): name = data['mapName'] playersNum = int(data['playersNum']) result = list() #checkFiles(data['thumbnail'], data['picture']) data['thumbnail'] = data[ 'thumbnail'] if 'thumbnail' in data else misc.DEFAULT_THUMB data['picture'] = data[ 'picture'] if 'picture' in data else misc.DEFAULT_MAP_PICTURE newMap = Map(name, playersNum, data['turnsNum'], data['thumbnail'], data['picture']) dbi.addUnique(newMap, 'mapName') mapId = newMap.id if 'regions' in data: regions = data['regions'] curId = 1 for regInfo in regions: try: dbi.addRegion(curId, newMap, regInfo) except KeyError, e: raise BadFieldException('badRegions') curId += 1 i = 0 for reg in newMap.regions: regInfo = data['regions'][i] if reg.id in regInfo['adjacent']: raise BadFieldException('badRegions') dbi.addAll( map(lambda x: Adjacency(reg.id, x, mapId), regInfo['adjacent'])) i += 1
def act_createGame(data): user = dbi.getXbyY('User', 'sid', data['sid']) if user.gameId: raise BadFieldException('alreadyInGame') map_ = dbi.getXbyY('Map', 'id', data['mapId']) descr = None if 'gameDescription' in data: descr = data['gameDescription'] randseed = math.trunc(time.time()) if 'randseed' in data: randseed = data['randseed'] ai = data['ai'] if 'ai' in data else 0 if ai > map_.playersNum: raise BadFieldException('tooManyPlayersForMap') newGame = Game(data['gameName'], descr, map_, randseed, data['ai'] if 'ai' in\ data else None) dbi.addUnique(newGame, 'gameName') initRegions(map_, newGame) if ai < map_.playersNum: user.game = newGame user.priority = 1 user.inGame = True dbi.flush(user) if not misc.TEST_MODE: data['randseed'] = randseed dbi.updateGameHistory(user.game, data) return {'result': 'ok', 'gameId': newGame.id}
def getNextRaceAndPowerFromStack(game, vRace, vSpecialPower): if vRace != None and vSpecialPower != None: race = filter(lambda x: x.name == vRace, races.racesList) if not race: raise BadFieldException('badRace') raceId = races.racesList.index(race[0]) specialPower = filter(lambda x: x.name == vSpecialPower, races.specialPowerList) if not specialPower: raise BadFieldException('badStage') specialPowerId = races.specialPowerList.index(specialPower[0]) else: racesInStack = range(0, misc.RACE_NUM) specialPowersInStack = range(0, misc.SPECIAL_POWER_NUM) tokenBadges = dbi.query(TokenBadge).filter( TokenBadge.gameId == game.id).all() for tokenBadge in tokenBadges: racesInStack.remove(tokenBadge.raceId) specialPowersInStack.remove(tokenBadge.specPowId) if misc.TEST_MODE: raceId = random.choice(racesInStack) specialPowerId = random.choice(specialPowersInStack) else: raceId = racesInStack[generateNextNum(game) % len(racesInStack)] specialPowerId = specialPowersInStack[generateNextNum(game) % len(specialPowersInStack)] return raceId, specialPowerId
def act_register(data): username = data['username'] passwd = data['password'] if not re.match(misc.usrnameRegexp, username, re.I): raise BadFieldException('badUsername') if not re.match(misc.pwdRegexp, passwd, re.I): raise BadFieldException('badPassword') dbi.addUnique(User(username, passwd), 'username') return {'result': 'ok'}
def checkListCorrectness(data, field, type): msg = 'bad' + field[0].upper() + field[1:] if not field in data: raise BadFieldException(msg) for t in data[field]: if not isinstance(t, type): if type is str and not isinstance(t, unicode): raise BadFieldException(msg)
def act_decline(data): user = dbi.getXbyY('User', 'sid', data['sid']) if not (user.game and user.inGame): raise BadFieldException('notInGame') if not user.currentTokenBadge: raise BadFieldException('badStage') checkStage(GAME_DECLINE, user) makeDecline(user) dbi.updateHistory(user, GAME_DECLINE, user.declinedTokenBadge.id) dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def act_defend(data): ## Should be renamed to retreat user = dbi.getXbyY('User', 'sid', data['sid']) if not (user.game and user.inGame): raise BadFieldException('notInGame') tokenBadge = user.currentTokenBadge if not tokenBadge: raise BadFieldException('badStage') checkStage(GAME_DEFEND, user) attackedRegion = user.game.getDefendingRegion(user) raceId, specialPowerId = tokenBadge.raceId, tokenBadge.specPowId notAdjacentRegions = [] for terr in tokenBadge.regions: if terr.region.id not in attackedRegion.getNeighbors(): ##~~ notAdjacentRegions.append(terr.region.id) for region in data['regions']: if not 'regionId' in region: raise BadFieldException('badRegionId') if not 'tokensNum' in region: raise BadFieldException('badTokensNum') if not isinstance(region['regionId'], int): raise BadFieldException('badRegionId') if not isinstance(region['tokensNum'], int): raise BadFieldException('badTokensNum') if user.tokensInHand < region['tokensNum']: raise BadFieldException('notEnoughTokens') destination = user.game.map.getRegion(region['regionId']) destState = destination.getState(user.game.id) if notAdjacentRegions and destination.id not in notAdjacentRegions or destState.owner.id != user.id: raise BadFieldException('badRegion') destState.tokensNum += region['tokensNum'] user.tokensInHand -= region['tokensNum'] if user.tokensInHand: raise BadFieldException('thereAreTokensInTheHand') dbi.updateHistory(user, GAME_DEFEND, tokenBadge.id) dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def act_selectFriend(data): user = dbi.getXbyY('User', 'sid', data['sid']) if not (user.game and user.inGame): raise BadFieldException('notInGame') if not user.currentTokenBadgeId: raise BadFieldException('badStage') checkStage(GAME_CHOOSE_FRIEND, user) callSpecialPowerMethod(user.currentTokenBadge.specPowId, 'selectFriend', user, data) dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def act_dragonAttack(data): user = dbi.getXbyY('User', 'sid', data['sid']) if not (user.game and user.inGame): raise BadFieldException('notInGame') if not user.currentTokenBadge: raise BadFieldException('badStage') checkStage(GAME_CONQUER, user, ATTACK_DRAGON) callSpecialPowerMethod( user.currentTokenBadge.specPowId, 'dragonAttack', user.currentTokenBadge, user.game.map.getRegion(data['regionId']).getState(user.game.id)) dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def checkObjectsListCorrection(data, fields): for obj in data: for field in fields: msg = 'bad' + field['name'][0].upper() + field['name'][1:] if not(field['name'] in obj): raise BadFieldException(msg) if not isinstance(obj[field['name']], field['type']): raise BadFieldException(msg) if 'min' in field: if obj[field['name']] < field['min']: raise BadFieldException(msg)
def sendCmd(self, obj): self.conn.request("POST", "", json.dumps( obj)) #self.conn.request("POST", "/small_worlds", json.dumps(obj)) res = self.conn.getresponse().read() data = json.loads(res) if not 'result' in data: raise BadFieldException('Unknown result') if (data['result'] in ('badJson', 'badReadinessStatus', 'badUserSid', 'badGameId', 'badMapId', 'badPosition', 'badFriendId', 'badRegionId')): raise BadFieldException(data['result']) return data
def act_throwDice(data): user = dbi.getXbyY('User', 'sid', data['sid']) if not (user.game and user.inGame): raise BadFieldException('notInGame') if not user.currentTokenBadge or not user.tokensInHand: raise BadFieldException('badStage') checkStage(GAME_THROW_DICE, user) specialPowerId = user.currentTokenBadge.specPowId dice = callSpecialPowerMethod(specialPowerId, 'throwDice', user.game, data['dice'] if 'dice' in data else 0) dbi.updateHistory(user, GAME_THROW_DICE, user.currentTokenBadge.id, dice) dbi.updateGameHistory(user.game, data) return {'result': 'ok', 'dice': dice}
def act_joinGame(data): user = dbi.getXbyY('User', 'sid', data['sid']) if user.game: raise BadFieldException('alreadyInGame') game = dbi.getXbyY('Game', 'id', data['gameId']) if game.state != GAME_WAITING: raise BadFieldException('badGameState') maxPlayersNum = game.map.playersNum if len(game.players) >= maxPlayersNum: raise BadFieldException('tooManyPlayers') maxPriority = max(game.players, key=lambda x: x.priority).priority user.game = game user.inGame = True user.priority = maxPriority + 1 dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def setEncampments(self, tokenBadge, encampments, data): checkObjectsListCorrection(encampments, [{'name': 'regionId', 'type': int, 'min': 1}, {'name': 'encampmentsNum', 'type': int, 'min': 0}]) game = tokenBadge.Owner().game freeEncampments = 5 for encampment in encampments: region = game.map.getRegion(encampment['regionId']).getState(game.id) encampmentsNum = encampment['encampmentsNum'] if region.tokenBadge != tokenBadge or not region.tokensNum: raise BadFieldException('badRegion') if encampmentsNum > freeEncampments: raise BadFieldException('notEnoughEncampmentsForRedeployment') region.encampment = encampmentsNum freeEncampments -= encampmentsNum
def act_leaveGame(data): user = dbi.getXbyY('User', 'sid', data['sid']) game = user.game if not (game and user.inGame): raise BadFieldException('notInGame') misc_game.leave(user) dbi.updateGameHistory(game, data) return {'result': 'ok'}
def selectFriend(self, user, data): if not('friendId' in data and isinstance(data['friendId'], int)): raise BadFieldException('badFriendId') friend = dbi.getXbyY('User', 'id', data['friendId']) if friend.id == user.id or friend.game.id != user.game.id: raise BadFieldException('badFriend') curTurnHistory = filter(lambda x: x.turn == user.game.turn and x.userId == user.id and x.state == GAME_CONQUER, user.game.history) if curTurnHistory: if friend.currentTokenBadge and filter(lambda x: x.warHistory.victimBadgeId == friend.currentTokenBadge.id, curTurnHistory): raise BadFieldException('badFriend') dbi.updateHistory(user, GAME_CHOOSE_FRIEND, user.currentTokenBadge.id, None, friend.id)
def finishTurn(self): data = self.sendCmd({'action': 'finishTurn', 'sid': self.sid}) if data['result'] != 'ok': raise BadFieldException('unknown error in finish turn %s' % data['result']) result = '' if 'ended' in data: #game ended #result += '***FINISH GAME***\n' #result += 'Game id: %d\n' % self.game.id statistics = data['statistics'] statistics = sorted(statistics, key=itemgetter('coins', 'regions'), reverse=True) for stat in statistics: result += 'Name: %s, coins: %d, regions: %d\n' % ( stat['username'], stat['coins'], stat['regions']) #result += '**************\n' result += '\n' self.logFile.write(result) else: result = 'Game id: %d, turn: %d\n' % (self.game.id, self.game.turn) result += 'Player id: %d\n' % self.id result += 'Statistics: \n' totalCoins = 0 for statistics in data['statistics']: result += '%s: %d\n' % (statistics[0], statistics[1]) totalCoins += statistics[1] result += 'Income coins: %d\n\n\n' % totalCoins #self.logFile.write(result) self.conqueredRegions = list() self.dragonUsed = False #regions self.enchantUsed = False self.friendId = None
def checkStage(state, user, attackType=None): game = user.game lastEvent = game.history[-1] badStage = not (lastEvent.state in misc.possiblePrevCmd[state]) if attackType: curTurnHistory = filter( lambda x: x.turn == user.game.turn and x.userId == user.id and x. state == misc.GAME_CONQUER, game.history) if curTurnHistory: if filter(lambda x: x.warHistory.attackType == attackType, curTurnHistory): badStage = True if lastEvent.state == misc.GAME_CONQUER: battle = lastEvent.warHistory victim = battle.victimBadge canDefend = victim != None and\ not victim.inDecline and\ battle.attackType != misc.ATTACK_ENCHANT and\ battle.victimTokensNum > callRaceMethod(victim.raceId, 'getCasualties') and\ len(victim.regions) > 0 badStage |= (canDefend != (state == misc.GAME_DEFEND)) or\ (state == misc.GAME_DEFEND and user.currentTokenBadge != victim) if badStage or (user.id != game.activePlayerId and state != misc.GAME_DEFEND): raise BadFieldException('badStage')
def parseJsonObj(obj): try: if not ('action' in obj): raise BadFieldException('badJson') else: ans = actions.doAction(obj) except BadFieldException, e: return {'result': e.value}
def act_setReadinessStatus(data): user = dbi.getXbyY('User', 'sid', data['sid']) game = user.game if not (game and user.inGame): raise BadFieldException('notInGame') if game.state != GAME_WAITING: raise BadFieldException('badGameState') user.isReady = data['isReady'] dbi.flush(user) maxPlayersNum = game.map.playersNum readyPlayersNum = dbi.query(User).filter(User.game == game).filter( User.isReady == True).count() if maxPlayersNum == readyPlayersNum: misc_game.startGame(game, user, data) dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def act_enchant(data): user = dbi.getXbyY('User', 'sid', data['sid']) if not (user.game and user.inGame): raise BadFieldException('notInGame') if not user.currentTokenBadge or user.currentTokenBadge.raceId != 9: raise BadFieldException('badStage') checkStage(GAME_CONQUER, user, ATTACK_ENCHANT) reg = user.game.map.getRegion(data['regionId']).getState(user.game.id) #print 'fff', reg.id, reg.tokenBadgeId if not reg.tokenBadge: raise BadFieldException('nothingToEnchant') victimBadgeId = reg.tokenBadge.id callRaceMethod(user.currentTokenBadge.raceId, 'enchant', user.currentTokenBadge, reg) #clearFromRace(reg) dbi.updateWarHistory(user, victimBadgeId, user.currentTokenBadge.id, None, reg.region.id, 1, ATTACK_ENCHANT) dbi.updateGameHistory(user.game, data) return {'result': 'ok'}
def setFortified(self, tokenBadge, fortified, data): if not('regionId' in fortified and isinstance(fortified['regionId'], int)): raise BadFieldException('badRegionId') user = tokenBadge.Owner() regionId = fortified['regionId'] regState = user.game.map.getRegion(regionId).getState(user.game.id) if regState.ownerId != tokenBadge.Owner().id or not regState.tokensNum: raise BadFieldException('badRegion') if regState.fortified: raise BadFieldException('tooManyFortifiedsInRegion') fortifiedsOnMap = len(filter(lambda x: x.fortified == True, tokenBadge.regions)) if fortifiedsOnMap >= self.maxNum: raise BadFieldException('tooManyFortifiedsOnMap') if fortifiedsOnMap == tokenBadge.specPowNum: raise BadFieldException('tooManyFortifieds') regState.fortified = True
def checkFiles(thumbSrc, pictSrc): path = os.path.dirname(__file__) sys.path.append(path) os.chdir(path) path1 = os.pardir path1 += '\\client' os.chdir(path1) if not(os.path.exists(thumbSrc) and os.path.exists(pictSrc)): raise BadFieldException("Thumbnail or picture files aren't found") os.chdir(path)
def checkFieldsCorrectness(data): fields = misc.actionFields[data['action']] if not fields: raise BadFieldException('actionDoesntExist') for field in fields: if not field['name'] in data: if field['mandatory']: raise BadFieldException(constructMsg(field)) for field in fields: if not field['name'] in data: continue msg = constructMsg(field) if not isinstance(data[field['name']], field['type']): raise BadFieldException(msg) minValue = field['min'] if 'min' in field else 0 maxValue = field['max'] if 'max' in field else sys.maxint value = data[field['name']] if field['type'] is int else len(data[field['name']]) if not minValue <= value <= maxValue: raise BadFieldException(msg)
def setHero(self, tokenBadge, heroes, data): checkObjectsListCorrection(heroes, [{'name': 'regionId', 'type': int, 'min': 1}]) if len(heroes) > 2: raise BadFieldException('badSetHeroCommand') if len(heroes) < 2 and len(data['regions']) > 1: raise BadFieldException('badSetHeroCommand') for region in tokenBadge.regions: region.hero = False user = tokenBadge.Owner() for hero in heroes: regState = user.game.map.getRegion(hero['regionId']).getState( user.game.id) if not regState.owner or regState.owner.currentTokenBadge != tokenBadge or\ not region.tokensNum: raise BadFieldException('badRegion') regState.hero = True
def enchant(self, tokenBadge, regState): game = tokenBadge.Owner().game victimBadge = regState.tokenBadge if not (self.canConquer(regState.region, tokenBadge) and specialPowerList[tokenBadge.specPowId].canConquer(regState.region, tokenBadge)): raise BadFieldException('badRegion') if not regState.inDecline: tokenBadge.Owner().checkForFriends(regState.owner) print 'v', victimBadge.id, tokenBadge.id if victimBadge.id == tokenBadge.id: raise BadFieldException('badAttackedRace') if not regState.tokensNum: raise BadFieldException('nothingToEnchant') if regState.tokensNum > 1: raise BadFieldException('cannotEnchantMoreThanOneToken') if regState.inDecline: raise BadFieldException('cannotEnchantDeclinedRace') regState.checkIfImmune(True) if tokenBadge.totalTokensNum == self.maxNum: raise BadFieldException('noMoreTokensInStorageTray') victimBadge.totalTokensNum -= 1 tokenBadge.totalTokensNum += 1 raceId, specialPowerId = victimBadge.raceId, victimBadge.specPowId regState.tokenBadge = tokenBadge regState.owner = tokenBadge.Owner() regState.tokensNum = 1
def doAction(data, check=True): try: dbi.session = dbi.Session() func = 'act_%s' % data['action'] if not (func in globals()): raise BadFieldException('badAction') if check: checkFieldsCorrectness(data) res = globals()[func](data) dbi.commit() return res except BadFieldException, e: print e dbi.rollback() return {'result': e.value}
def dragonAttack(self, tokenBadge, regState): regState.checkIfImmune() if not(racesList[tokenBadge.raceId].canConquer(regState.region, tokenBadge) and self.canConquer(regState.region, tokenBadge)): raise BadFieldException('badRegion') attackedTokenBadge = regState.tokenBadge attackedTokensNum = regState.tokensNum if attackedTokenBadge and attackedTokenBadge.id == tokenBadge.id: raise BadFieldException('badRegion') #misc_game.clearFromRace(regState) if regState.tokenBadge: race = racesList[regState.tokenBadge.raceId] race.clearRegion(regState.tokenBadge, regState) specialPower = specialPowerList[regState.tokenBadge.specialPowerId] specialPower.clearRegion(regState.tokenBadge, regState) if attackedTokenBadge: racesList[attackedTokenBadge.raceId].sufferCasualties(attackedTokenBadge) else: attackedTokensNum = 0 ##check anything else? for region in tokenBadge.regions: region.dragon = False regState.tokenBadge = tokenBadge regState.dragon = True regState.tokensNum = 1 regState.owner = tokenBadge.Owner() regState.inDecline = False tokenBadge.Owner().tokensInHand -= 1 if attackedTokenBadge: racesList[attackedTokenBadge.raceId].sufferCasualties(attackedTokenBadge) attackedTokenBadge.Owner().tokensInHand += attackedTokensNum - racesList[attackedTokenBadge.raceId].getCasualties() dbi.updateWarHistory(tokenBadge.Owner(), attackedTokenBadge.id if attackedTokenBadge else None, tokenBadge.id, None, regState.regionId, attackedTokensNum, ATTACK_DRAGON)