def get(self):
        Utils.reset(self)  # reset/clean standard variables

        # validate and assign parameters
        passwd = Utils.required(self, GCVars.passwd)
        guid = self.request.get('guid')
        uuid = Utils.required(self, 'uuid')
        uuid2 = Utils.required(self, 'uid2')
        events = Utils.required(self, 'events')
        events2 = Utils.required(self, 'events2')
        laptime = Utils.required(self, 'laptime')
        laptime2 = Utils.required(self, 'laptime2')
        track = Utils.required(self, 'track')

        version = config.data_version['building']
        if self.request.get('version'):
            version = self.request.get('version')
        lang = config.server["defaultLanguage"]
        if self.request.get('lang'):
            lang = self.request.get('lang')

        Utils.LogRequest(self)
        # check password
        if self.error == '' and passwd != config.testing['passwd']:
            self.error = 'passwd is incorrect.'

        start_time = time.time()  # start count

        # if error, skip this
        #if self.error != '' or self.error is None:
        player = Player.getplayer(self, uuid)
        player2 = Player.getplayer(self, uuid2)
        ai = None
        my_building = None

        win_prize = None
        lose_prize = None

        data = Data.getDataAsObj(self, 'opponent_en', 1.0)
        if data is None:
            opponents = {'obj': json.loads(Score.GetDefaultOpponents())}
        else:
            opponents = data.obj

        for _track in opponents:
            for opponent in opponents[_track]:
                if not win_prize:
                    win_prize = opponent['win_prize']
                if not lose_prize:
                    lose_prize = opponent['lose_prize']
                if player2 is None:
                    if opponent['id'] == uuid2:
                        ai = opponent
                        self.error = ''

        if player is not None and guid != '':
            if guid != player.state_obj['guid']:
                player = None
                self.error = config.error_message['dup_login']

        if player is not None:
            scores = Score.calculate(self, events, events2, laptime, laptime2,
                                     win_prize, lose_prize)

            if scores is not None:
                score = scores[0]['total']
                #player.state_obj['cash'] += score
                player.state_obj['updated'] = start_time

                if player2 is not None:
                    player.state_obj[GCVars.total_races] += 1
                    if laptime < laptime2:
                        player.state_obj[GCVars.total_wins] += 1

                if ai is not None:
                    # save the resource to a building, ready for collection
                    my_building = Building.save_resource_to_building(
                        self, lang, version, player.uuid, track, score)
                    if player.state_obj.has_key(GCVars.total_ai_races):
                        player.state_obj[GCVars.total_ai_races] += 1
                    else:
                        player.state_obj.setdefault(GCVars.total_ai_races, 1)

                    if laptime < laptime2:
                        if player.state_obj.has_key(GCVars.total_ai_wins):
                            player.state_obj[GCVars.total_ai_wins] += 1
                        else:
                            player.state_obj.setdefault(
                                GCVars.total_ai_wins, 1)

                        #find star rating
                        difference = float(laptime2) - float(laptime)
                        data = {}
                        star_value = 0
                        new_star_value = 0
                        if player.state_obj.has_key('data'):
                            data = json.loads(player.state_obj['data'])
                        if data.has_key(uuid2):
                            star_value = int(data[uuid2])

                        #0,2,4 = 1 start time, 2 start time, 3 star time
                        if difference > float(ai['1_star_time']):
                            new_star_value = 1
                        if difference > float(ai['2_star_time']):
                            new_star_value = 2
                        if difference > float(ai['3_star_time']):
                            new_star_value = 3

                        if new_star_value > star_value:
                            data[uuid2] = new_star_value

                        logging.debug(
                            str(new_star_value) + ' > star_value:' +
                            str(star_value) + ', laptime 1:' + str(laptime) +
                            ', laptime2: ' + str(laptime2))
                        logging.debug('setting player data to ' +
                                      json.dumps(data))

                        player.state_obj['data'] = json.dumps(data)
                        player.state = json.dumps(player.state_obj)

                Player.setplayer(self, player)
                if 'xxx' in player.state:
                    self.error += '[KNOWN ISSUE] Player car lost. Please visit showroom and buy X1 again.'

                player_score = scores[0]
                scores_to_return = {
                    'score_prize': player_score['prize'],
                    'score_drift': player_score['prizes']['drift_bonus'],
                    'score_shift': player_score['prizes']['shift_bonus'],
                    'score_start': player_score['prizes']['start_bonus']
                }

                logging.debug('finishrace player state:' + player.state)
                self.respn = '{"state":' + player.state
                self.respn += ',"scores":' + json.dumps(scores_to_return)
                if my_building is not None:
                    self.respn += ',"building":['
                    self.respn = Building.compose_mybuilding(
                        self.respn, my_building)
                    self.respn = self.respn.rstrip(',') + ']'
                self.respn += '}'

                if player2 is not None:
                    score = scores[1]['total']
                    #player2.state_obj[GCVars.cash] += score
                    Building.save_resource_to_building(self, lang, version,
                                                       player2.uuid, track,
                                                       score)
                    player2.state_obj[GCVars.updated] = start_time
                    player2.state_obj[GCVars.total_races] += 1
                    if laptime2 < laptime:
                        player2.state_obj[GCVars.total_wins] += 1
                    Player.setplayer(self, player2)
        else:
            self.error = 'Cant find a player for ' + uuid
            #else:
        #    logging.warn('final error ' + self.error)

        # calculate time taken and return the result
        time_taken = time.time() - start_time
        self.response.headers['Content-Type'] = 'text/html'
        self.response.write(Utils.RESTreturn(self, time_taken))
Exemplo n.º 2
0
    def Update(self, chid, type, uid, laptime, replay, events, cardata, name,
               image, lang, version):
        """ Parameters:
            chid - Challenge Id
            type - type of update, 'CHALLENGE' or 'ACCEPT'
            uid - user id, could be fbid or uuid
            replay - racing data
            score - button replay
        """
        my_building = None
        logging.debug("Challenge Update with replay length " +
                      str(len(replay)))
        challenge = memcache.get(config.db['challengedb_name'] + '.' + chid)

        if challenge is None:
            logging.debug("Challenge not found in memcache")
            challenges = Challenge.all().filter('id =', chid) \
                .filter('state !=', CHALLENGE_TYPE.BOTH_PLAYERS_FINISH) \
                .filter('state !=', CHALLENGE_TYPE.GAME_OVER) \
                .ancestor(db.Key.from_path('Challenge',config.db['challengedb_name'])) \
                .fetch(1)

            if len(challenges) > 0:
                challenge = challenges[0]
                logging.debug("Challenge found in data")
                if not memcache.add(config.db['challengedb_name'] + '.' + chid,
                                    challenge, config.memcache['holdtime']):
                    logging.warning(
                        'Challenge - Set memcache for challenge by Id failed (Update)!'
                    )

        if challenge is not None:
            logging.debug("Challenge is not none")
            #logging.debug("challenge update :" + challenge.data)
            #TODO: remove the replay data from the .data to prevent it being serialzed and back
            game = json.loads(challenge.data)
            _upd = False
            if challenge.state != CHALLENGE_TYPE.BOTH_PLAYERS_FINISH and challenge.state != CHALLENGE_TYPE.GAME_OVER:
                logging.info("challenge not over. state = " + challenge.state +
                             " type = " + type)

                start_time = time.time()
                # flag to prevent Player saving outside this function and loosing the changes
                challenge.manual_update = False

                #CHALLENGE_TYPE
                _player = 'player1'
                if type != CHALLENGE_MODE.CHALLENGE:
                    _player = 'player2'

                logging.info("updating _player " + _player)

                # find the key in the challenge data for the correct player and update the new state
                game[_player] = {
                    'player': {
                        'id': uid
                    },
                    'laptime': float(laptime),
                    'replay': replay,
                    'events': events,
                    'created': start_time,
                    'cardata': cardata,
                    'name': name,
                    'image': image
                }

                # update challenge state by looking at participants
                if not 'replay' in game['player1'] and not 'replay' in game[
                        'player2']:
                    challenge.state = CHALLENGE_TYPE.OPEN_GAME
                elif 'replay' in game['player1']:
                    challenge.state = CHALLENGE_TYPE.PLAYER1_FINISH
                elif 'replay' in game['player2']:
                    challenge.state = CHALLENGE_TYPE.PLAYER2_FINISH

                logging.info("challenge updating. state = " + challenge.state +
                             " type = " + type)

                # see if we can finish the challenge
                if game['player1'] is not None and game['player2'] is not None:
                    if 'replay' in game['player1'] and 'replay' in game[
                            'player2']:
                        challenge.state = CHALLENGE_TYPE.BOTH_PLAYERS_FINISH

                        # Update players with earnings
                        player1 = None
                        player2 = None
                        opponents = None
                        racewinnings = None
                        winner = 'draw'

                        player1 = Player.getplayerByFbid(self, challenge.uid1)
                        if player1 is None:
                            player1 = Player.getplayer(self, challenge.uid1)

                        if player1 is not None:
                            player2 = Player.getplayerByFbid(
                                self, challenge.uid2)
                            if player2 is None:
                                player2 = Player.getplayer(
                                    self, challenge.uid2)

                        if player2 is not None:
                            racewinnings = Data.getDataAsObj(
                                self, 'racewinnings',
                                config.data_version['racewinnings'])

                        if racewinnings is not None:
                            opponents = Data.getDataAsObj(
                                self, 'opponent_en',
                                config.data_version['opponent'])

                        # everything is good - we have 2 player models and the winnings data
                        if opponents is not None:
                            prize1 = 0
                            prize2 = 0

                            # only use the first one for multiplayer challenges
                            win_prize = opponents.obj[
                                challenge.track][0]['win_prize']
                            lose_prize = opponents.obj[
                                challenge.track][0]['lose_prize']

                            if game['player1']['laptime'] < game['player2'][
                                    'laptime']:  # player1 wins
                                winner = player1.uuid
                                prize1 = win_prize
                                prize2 = lose_prize
                                player1.state_obj['total_wins'] += 1
                            elif game['player1']['laptime'] > game['player2'][
                                    'laptime']:
                                winner = player2.uuid
                                prize1 = lose_prize
                                prize2 = win_prize
                                player2.state_obj['total_wins'] += 1
                            else:
                                winner = 'draw'
                                prize1 = lose_prize
                                prize2 = lose_prize
                            """
                            player2.state_obj['cash'] += prize1
                            player2.state_obj['cash'] += prize2
                            """

                            player1_building = Building.save_resource_to_building(
                                self, lang, version, player1.uuid,
                                challenge.track, prize1)
                            player2_building = Building.save_resource_to_building(
                                self, lang, version, player2.uuid,
                                challenge.track, prize2)

                            if uid == challenge.uid1:
                                my_building = player1_building
                            else:
                                player2.info_obj['updated'] = start_time
                                my_building = player2_building

                            if Player.setplayer(self, player2):
                                logging.info('player2 saved')

                            player1.state_obj['total_races'] += 1
                            player2.state_obj['total_races'] += 1

                            game['result'] = {
                                'winner': winner,
                                'player1': challenge.uid1,
                                'player2': challenge.uid2,
                                'player1_prize': prize1,
                                'player2_prize': prize2,
                                'player1_seen': uid == challenge.uid1,
                                'player2_seen': uid == challenge.uid2,
                                'player1_laptime': game['player1']['laptime'],
                                'player2_laptime': game['player2']['laptime']
                            }

                _upd = True

            # this can't be used - the player cannot do a challengeUpdate unless they finish a race?
            elif game['result']['player1_seen'] is False or game['result'][
                    'player2_seen'] is False:
                if uid == challenge.uid1:
                    game['result']['player1_seen'] = True
                    _upd = True
                if uid == challenge.uid2:
                    game['result']['player2_seen'] = True
                    _upd = True

                challenge.manual_update = True

            if game['result']['player1_seen'] and game['result'][
                    'player2_seen']:
                challenge.state = CHALLENGE_TYPE.GAME_OVER

            logging.debug("Update finished with state " + challenge.state +
                          " type = " + type)
            if _upd is True:
                challenge.data = json.dumps(game)
                if challenge.put():
                    # TODO : memcache replace
                    memcache.delete(config.db['challengedb_name'] + '.' +
                                    challenge.id)
                    if not memcache.add(
                            config.db['challengedb_name'] + '.' + challenge.id,
                            challenge):
                        logging.warning(
                            'Challenge - Set memcache for challenge by Id failed!'
                        )
                        self.error += 'Challenge saving failed :('
                else:
                    self.error += 'Challengeupdate failed :('

        else:
            self.error = 'Challenge ID=' + chid + ' could not be found.'
            logging.debug(self.error)

        return challenge, my_building