Пример #1
0
    def test_given_score_and_ThreeDisapprovingReviewerOfWhichTwoAgree_then_NonAgreeingReviewerAndPLayerAreCheater(self):
        score = {'score' : 99, 'proof' : "sdsd", 'time' : 0}
        playerId = "test"
        createPlayer(playerId, playerId)
        service.start(playerId)
        service.setScore(playerId, score)

        playerKey = Key.from_path('Player', playerId)

        createReviewerAndReview("test2", playerKey, {'score':3, 'time': 0})

        createReviewerAndReview("test3", playerKey, {'score':999, 'time': 0})

        createReviewerAndReview("test4", playerKey, {'score':3, 'time': 0})


        verifiedScore = VerifiedScore.get_by_key_name("verified", parent=playerKey)
        playerRecord = Record.get_by_key_name('record', parent=playerKey)

        self.assertTrue(verifiedScore is None or verifiedScore.value == 0)
        self.assertEqual(playerRecord.numCheat, 1)


        playerKey = Key.from_path('Player', 'test3')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)
Пример #2
0
    def test_given_score_and_TwoDisapprovingButNonAgreeingReviewerAndOneApprovingReviewer_then_NonApprovingReviewerAreCheater_and_playerVerifiedScoreIsUpdated(self):
        score = {'score' : 3, 'proof' : "sdsd", 'time' : 0}
        playerId = "test"
        createPlayer(playerId, playerId)
        service.start(playerId)
        service.setScore(playerId, score)

        playerKey = Key.from_path('Player', playerId)
        createReviewerAndReview("test2", playerKey, {'score':99, 'time': 0})

        createReviewerAndReview("test3", playerKey, {'score':999, 'time': 0})

        createReviewerAndReview("test4", playerKey, {'score':3, 'time': 0})

        verifiedScoreWrapper = VerifiedScoreWrapper.get_by_key_name('verifiedScore', parent=playerKey)
        verifiedScore = verifiedScoreWrapper.verified
        self.assertEqual(verifiedScore.value, 3)

        playerKey = Key.from_path('Player', 'test2')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)

        playerKey = Key.from_path('Player', 'test3')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)
Пример #3
0
    def test_given_aAdminReviewerTryingToReviewAsAdmin_ItShouldSucceedAndDeclareNonAgreeingConflictingReviewerAsCheaters(self):

        setReviewTimeUnit(0)
        score = {'score' : 99, 'proof' : "sdsd", 'time' : 0}
        playerId = "test"
        createPlayer(playerId, playerId)
        service.start(playerId)
        service.setScore(playerId, score)

        playerKey = Key.from_path('Player', playerId)

        createReviewerAndReview("test2", playerKey, {'score':3, 'time': 0})

        createReviewerAndReview("test3", playerKey, {'score':999, 'time': 0})

        createReviewerAndReview("test4", playerKey, {'score':3, 'time': 0}, True)


        verifiedScore = VerifiedScore.get_by_key_name("verified", parent=playerKey)
        playerRecord = Record.get_by_key_name('record', parent=playerKey)

        self.assertTrue(verifiedScore is None or verifiedScore.value == 0)
        self.assertEqual(playerRecord.numCheat, 1)


        playerKey = Key.from_path('Player', 'test3')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)

        playerKey = Key.from_path('Player', 'test2')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 0)
Пример #4
0
    def test_given_aAdminReviewerDisapprovingAnAlreadyVerifiedScore_ItShouldDeclareVerifierAsACheaterAndOtherAsNonCheaters(self):

        setReviewTimeUnit(0)
        score = {'score' : 99, 'proof' : "sdsd", 'time' : 0}
        playerId = "test"
        createPlayer(playerId, playerId)
        service.start(playerId)
        service.setScore(playerId, score)

        playerKey = Key.from_path('Player', playerId)

        createReviewerAndReview("test2", playerKey, {'score':3, 'time': 0})

        createReviewerAndReview("test3", playerKey, {'score':999, 'time': 0})

        createReviewerAndReview("test4", playerKey, {'score':99, 'time': 0}) # verified


        verifiedScoreWrapper = VerifiedScoreWrapper.get_by_key_name('verifiedScore', parent=playerKey)
        verifiedScore = verifiedScoreWrapper.verified
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertTrue(verifiedScore.value == 99)
        self.assertEqual(playerRecord.numCheat, 0)

        createPlayer('admin1', 'admin1')
        admin = getAdmin()
        admin.playerList.append('admin1')
        setAdmin(admin)
        service.getHighestNonApprovedScore('admin1')

        service.approveScore('admin1', {'score':3, 'time': 0})


        verifiedScoreWrapper = VerifiedScoreWrapper.get_by_key_name('verifiedScore', parent=playerKey)
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertTrue(verifiedScoreWrapper is None)
        self.assertEqual(playerRecord.numCheat, 1)

        playerKey = Key.from_path('Player', 'test3')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 0)

        playerKey = Key.from_path('Player', 'test2')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 0)

        playerKey = Key.from_path('Player', 'test4')
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)
Пример #5
0
    def _start():
        playerKey = Key.from_path('Player', playerId)

        rand = random.SystemRandom()
        seed = struct.pack("4L", rand.randint(1, MAX_INT32_VALUE),
                           rand.randint(1, MAX_INT32_VALUE),
                           rand.randint(1, MAX_INT32_VALUE),
                           rand.randint(1, MAX_INT32_VALUE))

        playSession = PlaySession(key_name='playSession',
                                  seed=seed,
                                  version=config.currentGameMechanicVersion,
                                  seedDateTime=datetime.datetime.now(),
                                  parent=playerKey)
        playSession.put()

        today = datetime.date.today()
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        if playerRecord.lastDayPlayed != today:
            playerRecord.numDaysPlayed += 1
            playerRecord.lastDayPlayed = today
            playerRecord.put()

        seedList = struct.unpack("4L", playSession.seed)
        return {'result': {'seed': seedList, 'version': playSession.version}}
Пример #6
0
    def _approveScore():
        scoreToApprove = db.get(scoreToApproveKey)
        if scoreToApprove is None:
            return {'cheater': None, 'nonCheaters': []}

        approvedPlayerKey = scoreToApprove.parent_key()

        cheater = None
        nonCheaters = []
        if scoreToApprove.value == scoreValue and scoreToApprove.time == scoreTime:
            scoreToApprove.approvedByAdmin = True
            scoreToApprove.put()
        else:
            approvedPlayerRecord = Record.get_by_key_name(
                'record', parent=approvedPlayerKey)
            approvedPlayerRecord.numCheat += 1
            approvedPlayerRecord.put()
            cheater = Key.from_path('Player', scoreToApprove.verifier)
            for nonCheaterId in scoreToApprove.conflictingReviewers:
                nonCheaters.append(Key.from_path('Player', nonCheaterId))
            scoreToApprove.delete()
            db.delete(
                Key.from_path('VerifiedScoreWrapper',
                              'verifiedScore',
                              parent=approvedPlayerKey))

        return {'cheater': cheater, 'nonCheaters': nonCheaters}
Пример #7
0
    def get(self):
        stats = getStats()

        lastPlayerRecords = Record.gql(
            "WHERE lastReviewAttemptDateTime > :firstDate ORDER BY lastReviewAttemptDateTime DESC",
            firstDate=datetime.datetime.min).fetch(
                1, config.nbPlayerPerTimeUnit - 1)

        if lastPlayerRecords is None or len(lastPlayerRecords) == 0:
            stats = setDefaultStats()
        else:
            lastPlayerRecordConsidered = lastPlayerRecords[0]
            now = datetime.datetime.now()

            timedelta = now - lastPlayerRecordConsidered.lastReviewAttemptDateTime

            #milliseconds
            newReviewTimeUnit = (timedelta.microseconds +
                                 (timedelta.seconds +
                                  timedelta.days * 24 * 3600) * 10**6) / 10**3

            reviewTimeUnitWeight = stats.reviewTimeUnitWeight
            stats.reviewTimeUnit = (
                reviewTimeUnitWeight * stats.reviewTimeUnit +
                newReviewTimeUnit) / (reviewTimeUnitWeight + 1)
            stats.reviewTimeUnitWeight = reviewTimeUnitWeight + 1

            setStats(stats)

        self.response.out.write(str(stats.reviewTimeUnit))
Пример #8
0
    def test_given_goodScoreWithWrongTime_thenPlayerIsCheater(self):
        score = {'score' : 3, 'proof' : "sdsd", 'time' : 0}
        playerId = "test"
        createPlayer(playerId, playerId)
        service.start(playerId)
        service.setScore(playerId, score)

        playerKey = Key.from_path('Player', playerId)

        createReviewerAndReview("test2", playerKey, {'score':3, 'time': 3})

        createReviewerAndReview("test3", playerKey, {'score':3, 'time': 3})

        verifiedScore = VerifiedScore.get_by_key_name("verified", parent=playerKey)
        self.assertTrue(verifiedScore is None or verifiedScore.value == 0)

        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)
Пример #9
0
    def _start():
        playerKey = Key.from_path('Player', playerId)

        rand = random.SystemRandom()
        seed = struct.pack("4L", rand.randint(1, MAX_INT32_VALUE), rand.randint(1, MAX_INT32_VALUE), rand.randint(1, MAX_INT32_VALUE), rand.randint(1, MAX_INT32_VALUE))

        playSession = PlaySession(key_name='playSession', seed=seed, version=config.currentGameMechanicVersion, seedDateTime=datetime.datetime.now(), parent=playerKey)
        playSession.put()

        today = datetime.date.today()
        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        if playerRecord.lastDayPlayed != today:
            playerRecord.numDaysPlayed += 1
            playerRecord.lastDayPlayed = today
            playerRecord.put()

        seedList = struct.unpack("4L", playSession.seed)
        return {'result' : { 'seed' : seedList, 'version': playSession.version } }
Пример #10
0
    def test_given_score_and_twoDisapprovingButAgreeingReviewers_then_playerIsCheater_and_verfiedScoreDoNotChange(self):
        score = {'score' : 99, 'proof' : "sdsd", 'time' : 0}
        playerId = "test"
        createPlayer(playerId, playerId)
        service.start(playerId)
        service.setScore(playerId, score)

        playerKey = Key.from_path('Player', playerId)

        createReviewerAndReview("test2", playerKey, {'score':3, 'time': 0})

        createReviewerAndReview("test3", playerKey, {'score':3, 'time': 0})

        verifiedScore = VerifiedScore.get_by_key_name("verified", parent=playerKey)
        self.assertTrue(verifiedScore is None or verifiedScore.value == 0)

        playerRecord = Record.get_by_key_name('record', parent=playerKey)
        self.assertEqual(playerRecord.numCheat, 1)
Пример #11
0
    def _approveScore():
        scoreToApprove = db.get(scoreToApproveKey)
        if scoreToApprove is None:
            return {'cheater' : None, 'nonCheaters': []}

        approvedPlayerKey = scoreToApprove.parent_key()

        cheater = None
        nonCheaters = []
        if scoreToApprove.value == scoreValue and scoreToApprove.time == scoreTime:
            scoreToApprove.approvedByAdmin = True
            scoreToApprove.put()
        else:
            approvedPlayerRecord = Record.get_by_key_name('record', parent=approvedPlayerKey)
            approvedPlayerRecord.numCheat += 1
            approvedPlayerRecord.put()
            cheater = Key.from_path('Player', scoreToApprove.verifier)
            for nonCheaterId in scoreToApprove.conflictingReviewers:
                nonCheaters.append(Key.from_path('Player', nonCheaterId))
            scoreToApprove.delete()
            db.delete(Key.from_path('VerifiedScoreWrapper', 'verifiedScore', parent = approvedPlayerKey))

        return {'cheater' : cheater, 'nonCheaters': nonCheaters}
Пример #12
0
 def _cheaterUpdate(cheaterKey):
     cheaterRecord = Record.get_by_key_name('record', parent=cheaterKey)
     cheaterRecord.numCheat+=1
     cheaterRecord.put()
Пример #13
0
 def _cheaterUpdate(cheaterKey):
     cheaterRecord = Record.get_by_key_name('record', parent=cheaterKey)
     cheaterRecord.numCheat += 1
     cheaterRecord.put()
Пример #14
0
def _checkConflicts(scoreToReviewKey, scoreValue, scoreTime, playerId,
                    adminMode):
    playerKey = Key.from_path('Player', playerId)

    scoreToReview = db.get(scoreToReviewKey)
    if scoreToReview is None:
        return []

    cheaters = []
    conflictResolved = False
    if scoreToReview.value == scoreValue and scoreToReview.time == scoreTime:
        # delete the score (unverified) and reset a verifiedScore
        reviewedPlayerKey = scoreToReview.parent_key()
        verifiedScore = VerifiedScore(
            parent=reviewedPlayerKey,
            value=scoreToReview.value,
            proof=scoreToReview.proof,
            time=scoreToReview.time,
            seed=scoreToReview.seed,
            version=scoreToReview.version,
            conflictingReviewers=scoreToReview.conflictingReviewers,
            verifier=playerId,
            approvedByAdmin=adminMode)
        verifiedScore.put()
        verifiedScoreWrapper = VerifiedScoreWrapper.get_by_key_name(
            "verifiedScore", parent=reviewedPlayerKey)
        if verifiedScoreWrapper is None:
            verifiedScoreWrapper = VerifiedScoreWrapper(
                key_name='verifiedScore',
                parent=reviewedPlayerKey,
                verified=verifiedScore)
        else:
            verifiedScoreWrapper.verified.delete()
            verifiedScoreWrapper.verified = verifiedScore
        verifiedScoreWrapper.put()
        reviewedPlayerRecord = Record.get_by_key_name('record',
                                                      parent=reviewedPlayerKey)
        reviewedPlayerRecord.numScoreVerified += 1
        reviewedPlayerRecord.put()
        db.delete(
            Key.from_path('PendingScore',
                          'pendingScore',
                          parent=reviewedPlayerKey))
        #delete conflicts and set conflicting reviewers as cheater
        conflicts = ReviewConflict.gql("WHERE ANCESTOR IS :score",
                                       score=scoreToReview).fetch(
                                           100)  # shoud not be more than 2
        for conflict in conflicts:
            if ReviewConflict.player.get_value_for_datastore(
                    conflict) == playerKey and not adminMode:
                pass  #TODO : raise Exception("this player has been able to review two times the same score!")
            if conflict.scoreValue != scoreValue or conflict.scoreTime != scoreTime:
                cheaters.append(
                    ReviewConflict.player.get_value_for_datastore(conflict))
            conflict.delete()
        scoreToReview.delete()
        conflictResolved = True
    else:
        #check whether a conflict exist with the same score value, if that is the case, player has cheated
        conflicts = ReviewConflict.gql("WHERE ANCESTOR IS :score",
                                       score=scoreToReview).fetch(
                                           100)  # should not be more than 3

        if adminMode:
            conflictResolved = True  # player is cheater no need to check anything else
        else:
            for conflict in conflicts:
                if ReviewConflict.player.get_value_for_datastore(
                        conflict) == playerKey:
                    pass  #TODO : raise Exception("this player has been able to review two times the same score!")
                elif conflict.scoreValue == scoreValue and conflict.scoreTime == scoreTime:
                    conflictResolved = True
                    break

        #player is a cheater
        if conflictResolved:
            reviewedPlayerKey = scoreToReview.parent_key()
            reviewedPlayerRecord = Record.get_by_key_name(
                'record', parent=reviewedPlayerKey)
            reviewedPlayerRecord.numCheat += 1
            reviewedPlayerRecord.put()
            #remove stuffs and assign cheater status to reviewer
            for conflict in conflicts:
                if conflict.scoreValue != scoreValue or conflict.scoreTime != scoreTime:
                    cheaters.append(
                        ReviewConflict.player.get_value_for_datastore(
                            conflict))
                conflict.delete()
            scoreToReview.delete()
            db.delete(
                Key.from_path('PendingScore',
                              'pendingScore',
                              parent=reviewedPlayerKey))

        else:
            scoreToReview.conflictingReviewers.append(playerId)
            scoreToReview.put()
            newConflict = ReviewConflict(player=playerKey,
                                         scoreValue=scoreValue,
                                         scoreTime=scoreTime,
                                         parent=scoreToReview)
            newConflict.put()

    return cheaters
Пример #15
0
def approveScore(playerId, score):
    admin = getAdmin()
    try:
        admin.playerList.index(playerId)
    except ValueError:
        return getErrorResponse(ADMIN_ONLY)

    scoreValue = score['score']
    scoreTime = score['time']
    playerKey = Key.from_path('Player', playerId)
    approveSession = ApproveSession.get_by_key_name('approveSession',
                                                    parent=playerKey)

    if approveSession is None:
        return getErrorResponse(NOTHING_TO_REVIEW)

    scoreToApproveKey = ApproveSession.currentScoreToApprove.get_value_for_datastore(
        approveSession)
    # We are done with it
    approveSession.delete()

    def _approveScore():
        scoreToApprove = db.get(scoreToApproveKey)
        if scoreToApprove is None:
            return {'cheater': None, 'nonCheaters': []}

        approvedPlayerKey = scoreToApprove.parent_key()

        cheater = None
        nonCheaters = []
        if scoreToApprove.value == scoreValue and scoreToApprove.time == scoreTime:
            scoreToApprove.approvedByAdmin = True
            scoreToApprove.put()
        else:
            approvedPlayerRecord = Record.get_by_key_name(
                'record', parent=approvedPlayerKey)
            approvedPlayerRecord.numCheat += 1
            approvedPlayerRecord.put()
            cheater = Key.from_path('Player', scoreToApprove.verifier)
            for nonCheaterId in scoreToApprove.conflictingReviewers:
                nonCheaters.append(Key.from_path('Player', nonCheaterId))
            scoreToApprove.delete()
            db.delete(
                Key.from_path('VerifiedScoreWrapper',
                              'verifiedScore',
                              parent=approvedPlayerKey))

        return {'cheater': cheater, 'nonCheaters': nonCheaters}

    try:
        result = db.run_in_transaction(_approveScore)
    except TransactionFailedError:
        return getErrorResponse(APPROVESCORE_TRANSACTION_FAILURE, 0)

    cheater = result['cheater']
    nonCheaters = result['nonCheaters']

    if cheater is not None:
        cheaterRecord = Record.get_by_key_name('record', parent=cheater)
        cheaterRecord.numCheat += 1
        cheaterRecord.put()

    if nonCheaters:

        def _nonCheaterUpdate(nonCheaterKey):
            cheaterRecord = Record.get_by_key_name('record',
                                                   parent=nonCheaterKey)
            cheaterRecord.numCheat -= 1
            cheaterRecord.put()

        for nonCheaterKey in nonCheaters:
            db.run_in_transaction(_nonCheaterUpdate, nonCheaterKey)

    return {'result': {'message': 'approvement submited'}}
Пример #16
0
 def _nonCheaterUpdate(nonCheaterKey):
     cheaterRecord = Record.get_by_key_name('record',
                                            parent=nonCheaterKey)
     cheaterRecord.numCheat -= 1
     cheaterRecord.put()
Пример #17
0
 def _nonCheaterUpdate(nonCheaterKey):
     cheaterRecord = Record.get_by_key_name('record', parent=nonCheaterKey)
     cheaterRecord.numCheat-=1
     cheaterRecord.put()
Пример #18
0
def approveScore(playerId, score):
    admin = getAdmin()
    try:
        admin.playerList.index(playerId)
    except ValueError:
        return getErrorResponse(ADMIN_ONLY)

    scoreValue = score['score']
    scoreTime = score['time']
    playerKey = Key.from_path('Player', playerId)
    approveSession = ApproveSession.get_by_key_name('approveSession', parent=playerKey)

    if approveSession is None:
        return getErrorResponse(NOTHING_TO_REVIEW)

    scoreToApproveKey = ApproveSession.currentScoreToApprove.get_value_for_datastore(approveSession)
    # We are done with it
    approveSession.delete()

    def _approveScore():
        scoreToApprove = db.get(scoreToApproveKey)
        if scoreToApprove is None:
            return {'cheater' : None, 'nonCheaters': []}

        approvedPlayerKey = scoreToApprove.parent_key()

        cheater = None
        nonCheaters = []
        if scoreToApprove.value == scoreValue and scoreToApprove.time == scoreTime:
            scoreToApprove.approvedByAdmin = True
            scoreToApprove.put()
        else:
            approvedPlayerRecord = Record.get_by_key_name('record', parent=approvedPlayerKey)
            approvedPlayerRecord.numCheat += 1
            approvedPlayerRecord.put()
            cheater = Key.from_path('Player', scoreToApprove.verifier)
            for nonCheaterId in scoreToApprove.conflictingReviewers:
                nonCheaters.append(Key.from_path('Player', nonCheaterId))
            scoreToApprove.delete()
            db.delete(Key.from_path('VerifiedScoreWrapper', 'verifiedScore', parent = approvedPlayerKey))

        return {'cheater' : cheater, 'nonCheaters': nonCheaters}

    try:
        result = db.run_in_transaction(_approveScore)
    except TransactionFailedError:
        return getErrorResponse(APPROVESCORE_TRANSACTION_FAILURE, 0)

    cheater = result['cheater']
    nonCheaters = result['nonCheaters']

    if cheater is not None:
        cheaterRecord = Record.get_by_key_name('record', parent=cheater)
        cheaterRecord.numCheat+=1
        cheaterRecord.put()

    if nonCheaters:
        def _nonCheaterUpdate(nonCheaterKey):
            cheaterRecord = Record.get_by_key_name('record', parent=nonCheaterKey)
            cheaterRecord.numCheat-=1
            cheaterRecord.put()

        for nonCheaterKey in nonCheaters:
            db.run_in_transaction(_nonCheaterUpdate,nonCheaterKey)

    return {'result' : { 'message' : 'approvement submited'} }
Пример #19
0
 def _increaseNumScoreReviewed():
     playerRecord = Record.get_by_key_name('record', parent=playerKey)
     playerRecord.numScoreReviewed += 1
     playerRecord.put()
Пример #20
0
 def _increaseNumScoreReviewed():
     playerRecord = Record.get_by_key_name('record', parent=playerKey)
     playerRecord.numScoreReviewed += 1
     playerRecord.put()
Пример #21
0
def getRandomScore(playerId):

    playerKey = Key.from_path('Player', playerId)

    playerRecord = Record.get_by_key_name('record', parent=playerKey)

    # do not review if you are a cheater
    if playerRecord.numCheat > 0:
        return getErrorResponse(CHEATER_BLOCKED)

    reviewTimeUnitMilliseconds = getReviewTimeUnit()
    reviewTimeUnit = datetime.timedelta(milliseconds=reviewTimeUnitMilliseconds)
    now =datetime.datetime.now()
    oldEnoughTime = now - reviewTimeUnit

    delay = 2000 + random.random() * 5000  + ceil(reviewTimeUnitMilliseconds * (1 + random.random() * 2))
    if delay > MAX_INT32_VALUE:
        delay = MAX_INT32_VALUE

    def _updateLastReviewAttemptDateTime():
        if playerRecord.lastReviewAttemptDateTime is not None and playerRecord.lastReviewAttemptDateTime > oldEnoughTime:
            # TODO : check whethe rthis randomize stuff is good or not:
            return {'result' : {'message' : 'You already posted enough reviews, retry later', 'retry' : delay } }
            # could be 2 * reviewTimeUnit / config.nbPlayerPerTimeUnit

        playerRecord.lastReviewAttemptDateTime = datetime.datetime.now()
        playerRecord.put()
        return None

    reviewSession = ReviewSession.get_by_key_name('reviewSession', parent=playerKey)
    if reviewSession is None:

        try:
            result = db.run_in_transaction(_updateLastReviewAttemptDateTime)
        except TransactionFailedError:
            result = getErrorResponse(LASTREVIEWUPDATE_TRANSACTION_FAILURE, 0)

        if result is not None:
            return result

        # do not allow reviewer to jump on a just posted review. basically the reviewer should have lots of potential review to take from and other reviewer shoudl compete with
        potentialScoresToReview = db.GqlQuery("SELECT * FROM NonVerifiedScore WHERE dateTime < :oldEnoughTime ORDER BY dateTime ASC", oldEnoughTime=oldEnoughTime).fetch(5)

        scoreToReview = None
        for score in potentialScoresToReview:
            if score.parent_key() != playerKey:
                try:
                    score.conflictingReviewers.index(playerId)
                except ValueError: # the current reviewer did not review this score yet
                    scoreToReview = score
                    break

        if scoreToReview is None:
            return {'result' : {'message' : 'Nothing to review for now', 'retry' : delay } }


        reviewSession = ReviewSession(key_name='reviewSession', currentScoreToReview=scoreToReview, parent=playerKey)
        reviewSession.put()
    else:
        try:
            scoreToReview = reviewSession.currentScoreToReview
        except ReferencePropertyResolveError:
            scoreToReview = None
            
    # in case score has been approved just now, it could have been removed
    if scoreToReview is not None:
        seedList = struct.unpack("4L", scoreToReview.seed)
        return {'result' : { 'proof' : scoreToReview.proof, 'seed' : seedList, 'version' : scoreToReview.version} }

    return {'result' : {'message' : 'Nothing to review for now (just done)', 'retry' : delay} }
Пример #22
0
def _checkConflicts(scoreToReviewKey, scoreValue, scoreTime, playerId, adminMode):
    playerKey = Key.from_path('Player', playerId)

    scoreToReview = db.get(scoreToReviewKey)
    if scoreToReview is None:
        return []

    cheaters = []
    conflictResolved = False
    if scoreToReview.value == scoreValue and scoreToReview.time == scoreTime:
        # delete the score (unverified) and reset a verifiedScore
        reviewedPlayerKey = scoreToReview.parent_key()
        verifiedScore = VerifiedScore(parent=reviewedPlayerKey, value=scoreToReview.value, proof=scoreToReview.proof, time=scoreToReview.time, seed=scoreToReview.seed, version=scoreToReview.version, conflictingReviewers=scoreToReview.conflictingReviewers, verifier=playerId, approvedByAdmin=adminMode)
        verifiedScore.put()
        verifiedScoreWrapper = VerifiedScoreWrapper.get_by_key_name("verifiedScore", parent=reviewedPlayerKey)
        if verifiedScoreWrapper is None:
            verifiedScoreWrapper = VerifiedScoreWrapper(key_name='verifiedScore', parent=reviewedPlayerKey, verified=verifiedScore)
        else:
            verifiedScoreWrapper.verified.delete()
            verifiedScoreWrapper.verified = verifiedScore
        verifiedScoreWrapper.put()
        reviewedPlayerRecord = Record.get_by_key_name('record', parent=reviewedPlayerKey)
        reviewedPlayerRecord.numScoreVerified += 1
        reviewedPlayerRecord.put()
        db.delete(Key.from_path('PendingScore', 'pendingScore', parent = reviewedPlayerKey))
        #delete conflicts and set conflicting reviewers as cheater
        conflicts = ReviewConflict.gql("WHERE ANCESTOR IS :score", score=scoreToReview).fetch(100) # shoud not be more than 2
        for conflict in conflicts:
            if ReviewConflict.player.get_value_for_datastore(conflict) == playerKey and not adminMode:
                pass #TODO : raise Exception("this player has been able to review two times the same score!")
            if conflict.scoreValue != scoreValue or conflict.scoreTime != scoreTime:
                cheaters.append(ReviewConflict.player.get_value_for_datastore(conflict))
            conflict.delete()
        scoreToReview.delete()
        conflictResolved = True
    else:
        #check whether a conflict exist with the same score value, if that is the case, player has cheated
        conflicts = ReviewConflict.gql("WHERE ANCESTOR IS :score", score=scoreToReview).fetch(100) # should not be more than 3

        if adminMode:
            conflictResolved = True # player is cheater no need to check anything else
        else:
            for conflict in conflicts:
                if ReviewConflict.player.get_value_for_datastore(conflict) == playerKey:
                    pass #TODO : raise Exception("this player has been able to review two times the same score!")
                elif conflict.scoreValue == scoreValue and conflict.scoreTime == scoreTime:
                    conflictResolved = True
                    break

        #player is a cheater
        if conflictResolved:
            reviewedPlayerKey = scoreToReview.parent_key()
            reviewedPlayerRecord = Record.get_by_key_name('record', parent=reviewedPlayerKey)
            reviewedPlayerRecord.numCheat+=1
            reviewedPlayerRecord.put()
            #remove stuffs and assign cheater status to reviewer
            for conflict in conflicts:
                if conflict.scoreValue != scoreValue or conflict.scoreTime != scoreTime:
                    cheaters.append(ReviewConflict.player.get_value_for_datastore(conflict))
                conflict.delete()
            scoreToReview.delete()
            db.delete(Key.from_path('PendingScore', 'pendingScore', parent = reviewedPlayerKey))

        else:
            scoreToReview.conflictingReviewers.append(playerId)
            scoreToReview.put()
            newConflict = ReviewConflict(player=playerKey,scoreValue=scoreValue,scoreTime=scoreTime, parent=scoreToReview)
            newConflict.put()


    return cheaters
Пример #23
0
def getRandomScore(playerId):

    playerKey = Key.from_path('Player', playerId)

    playerRecord = Record.get_by_key_name('record', parent=playerKey)

    # do not review if you are a cheater
    if playerRecord.numCheat > 0:
        return getErrorResponse(CHEATER_BLOCKED)

    reviewTimeUnitMilliseconds = getReviewTimeUnit()
    reviewTimeUnit = datetime.timedelta(
        milliseconds=reviewTimeUnitMilliseconds)
    now = datetime.datetime.now()
    oldEnoughTime = now - reviewTimeUnit

    delay = 2000 + random.random() * 5000 + ceil(reviewTimeUnitMilliseconds *
                                                 (1 + random.random() * 2))
    if delay > MAX_INT32_VALUE:
        delay = MAX_INT32_VALUE

    def _updateLastReviewAttemptDateTime():
        if playerRecord.lastReviewAttemptDateTime is not None and playerRecord.lastReviewAttemptDateTime > oldEnoughTime:
            # TODO : check whethe rthis randomize stuff is good or not:
            return {
                'result': {
                    'message':
                    'You already posted enough reviews, retry later',
                    'retry': delay
                }
            }
            # could be 2 * reviewTimeUnit / config.nbPlayerPerTimeUnit

        playerRecord.lastReviewAttemptDateTime = datetime.datetime.now()
        playerRecord.put()
        return None

    reviewSession = ReviewSession.get_by_key_name('reviewSession',
                                                  parent=playerKey)
    if reviewSession is None:

        try:
            result = db.run_in_transaction(_updateLastReviewAttemptDateTime)
        except TransactionFailedError:
            result = getErrorResponse(LASTREVIEWUPDATE_TRANSACTION_FAILURE, 0)

        if result is not None:
            return result

        # do not allow reviewer to jump on a just posted review. basically the reviewer should have lots of potential review to take from and other reviewer shoudl compete with
        potentialScoresToReview = db.GqlQuery(
            "SELECT * FROM NonVerifiedScore WHERE dateTime < :oldEnoughTime ORDER BY dateTime ASC",
            oldEnoughTime=oldEnoughTime).fetch(5)

        scoreToReview = None
        for score in potentialScoresToReview:
            if score.parent_key() != playerKey:
                try:
                    score.conflictingReviewers.index(playerId)
                except ValueError:  # the current reviewer did not review this score yet
                    scoreToReview = score
                    break

        if scoreToReview is None:
            return {
                'result': {
                    'message': 'Nothing to review for now',
                    'retry': delay
                }
            }

        reviewSession = ReviewSession(key_name='reviewSession',
                                      currentScoreToReview=scoreToReview,
                                      parent=playerKey)
        reviewSession.put()
    else:
        try:
            scoreToReview = reviewSession.currentScoreToReview
        except ReferencePropertyResolveError:
            scoreToReview = None

    # in case score has been approved just now, it could have been removed
    if scoreToReview is not None:
        seedList = struct.unpack("4L", scoreToReview.seed)
        return {
            'result': {
                'proof': scoreToReview.proof,
                'seed': seedList,
                'version': scoreToReview.version
            }
        }

    return {
        'result': {
            'message': 'Nothing to review for now (just done)',
            'retry': delay
        }
    }