def convert_mystery_box():
    mystery_rewards = EtheremonDB.TransactionTab.objects\
     .filter(txn_type=TxnTypes.LUNAR_19_REWARD)\
     .filter(amount_type=TxnAmountTypes.LUNAR_MYSTERY_BOX)\
     .filter(status=TxnStatus.INIT)

    with transaction.atomic():
        for reward in mystery_rewards:
            print("Converting", reward.id)
            for i in range(0, 5):
                transaction_manager.create_transaction(
                    reward.player_uid,
                    reward.player_address,
                    TxnTypes.LUNAR_19_REWARD_MYSTERY_BOX,
                    "unbox mystery - lvl",
                    TxnAmountTypes.ADV_LEVEL_STONE_1,
                    1,
                    status=TxnStatus.INIT,
                )

            transaction_manager.create_transaction(
                reward.player_uid,
                reward.player_address,
                TxnTypes.LUNAR_19_REWARD_MYSTERY_BOX,
                "unbox mystery - mon",
                TxnAmountTypes.LUNAR_MON,
                1,
                status=TxnStatus.INIT,
            )

            reward.status = TxnStatus.FINISHED
            reward.save()
def return_rewards(execute=False):
	for data in KING_OF_HILL_PLAYERS:
		name, address, rank, reward = data
		player_uid = user_manager.get_uid_by_address(address)

		if player_uid == "":
			print "player hasn't registered", address, reward
			continue

		with transaction.atomic():
			txn = transaction_manager.get_player_transactions(player_uid, TxnTypes.EVENT_KING_OF_HILL)

			if len(txn) == 0:
				print "ready to send reward", player_uid, address, reward

				if execute:
					emont_bonus_manager.add_bonus(player_uid, {
						EmontBonusType.EVENT_BONUS: reward
					})

					transaction_manager.create_transaction(
						player_uid=player_uid,
						player_address=address,
						txn_type=TxnTypes.EVENT_KING_OF_HILL,
						txn_info="",
						amount_type=TxnAmountTypes.IN_GAME_EMONT,
						amount_value=reward,
						status=TxnStatus.FINISHED
					)
Exemplo n.º 3
0
def update_lunar_egg_rebate():
	if get_timestamp() > LUNAR_19_END_TIME + 60:
		return

	bonus_eggs = EtheremonDB.EmaEggDataTab.objects.filter(mother_id=0).filter(create_time__gte=LUNAR_19_START_TIME).filter(create_time__lte=LUNAR_19_END_TIME).order_by("egg_id")[:888]

	egg_purchases = {}
	for data in bonus_eggs:
		egg_purchases[data.trainer] = egg_purchases.get(data.trainer, 0) + 1

	for address in egg_purchases:
		player_uid = user_manager.get_uid_by_address_default_0(address)
		if player_uid == 0:
			continue

		cc = min(8, egg_purchases[address]) * 88
		collected = transaction_manager.get_transactions(player_uid, TxnTypes.LUNAR_19_EMONT_REBATE).aggregate(sum=Sum('amount_value'))['sum']
		to_collect = max(0, round(cc - (collected or 0), 2))

		if to_collect > 0:
			with transaction.atomic():
				emont_bonus_manager.add_bonus(
					uid=player_uid,
					bonus_dict={
						EmontBonusType.EVENT_BONUS: to_collect
					}
				)
				transaction_manager.create_transaction(
					player_uid=player_uid,
					player_address=address,
					txn_type=TxnTypes.LUNAR_19_EMONT_REBATE,
					txn_info='{"past_collected": %s}' % collected,
					amount_type=TxnAmountTypes.IN_GAME_EMONT,
					amount_value=to_collect,
					status=TxnStatus.FINISHED
				)
				log.data("lunar_bonus|player=%s,collected=%s,collected=%s,to_collect=%s", address, player_uid, collected, to_collect)
Exemplo n.º 4
0
def spin_lucky_wheel(request, data):
    player_address = data['trainer_address'].lower()
    player_uid = data['player_uid']

    # verify trainer address
    if not Web3.isAddress(player_address):
        log.warn("send_to_address_invalid|data=%s", data)
        return api_response_result(
            request, ResultCode.ERROR_PARAMS,
            {"error_message": "invalid_send_to_address"})

    with transaction.atomic():
        # Deduct money & Reset adventure hongbao
        emont_bonus_manager.deduct_emont_in_game_balance(
            player_uid, LD_SPIN_COST_EMONT_COST)

        # Add payment txn
        transaction_manager.create_transaction(
            player_uid=player_uid,
            player_address=player_address,
            txn_type=TxnTypes.LUCKY_DRAW_PAYMENT,
            txn_info="lucky draw payment",
            amount_type=TxnAmountTypes.IN_GAME_EMONT,
            amount_value=LD_SPIN_COST_EMONT_COST,
            status=TxnStatus.FINISHED)

        # Find random reward
        random_perc = randint(0, 10000)
        random_reward = None
        for reward in LD_REWARDS:
            if random_perc < reward["percentage"]:
                random_reward = reward
                break
            else:
                random_perc -= reward["percentage"]

        if random_reward is None:
            log.warn("random_reward_failed|data=%s", data)
            return api_response_result(request, ResultCode.ERROR_SERVER,
                                       {"error_message": "server_error"})

        # Send reward
        if random_reward["reward_type"] == TxnAmountTypes.ENERGY:
            ema_energy_manager.add_energy(player_address,
                                          random_reward["reward_value"])
            txn_status = TxnStatus.FINISHED
        elif random_reward["reward_type"] == TxnAmountTypes.IN_GAME_EMONT:
            emont_bonus_manager.add_bonus(
                player_uid,
                {EmontBonusType.EVENT_BONUS: random_reward["reward_value"]})
            txn_status = TxnStatus.FINISHED
        elif random_reward["reward_type"] in [
                TxnAmountTypes.ADV_LEVEL_STONE_1,
                TxnAmountTypes.ADV_LEVEL_STONE_2
        ]:
            txn_status = TxnStatus.INIT
        else:
            txn_status = TxnStatus.FINISHED

        # Add reward txn
        transaction_manager.create_transaction(player_uid,
                                               player_address,
                                               TxnTypes.LUCKY_DRAW_REWARD,
                                               random_reward["desc"],
                                               random_reward["reward_type"],
                                               random_reward["reward_value"],
                                               status=txn_status)

        rewards = get_rewards(player_address)

        return api_response_result(
            request, ResultCode.SUCCESS, {
                "reward_idx":
                random_reward["idx"],
                "reward_type":
                random_reward["reward_type"],
                "reward_value":
                random_reward["reward_value"],
                "balance_emont_in_game":
                emont_bonus_manager.get_emont_balance(player_uid),
                "balance_energy":
                ema_energy_manager.get_available_energy(player_address),
                "current_rewards":
                rewards["current_rewards"],
                "to_claim_rewards":
                rewards["to_claim_rewards"],
                "spin_cost_emont":
                LD_SPIN_COST_EMONT_COST,
            })
Exemplo n.º 5
0
def start_tournament(tournament, tournament_id=None, force_restart=False):
    if tournament_id is not None:
        tournament = tournament_manager.get_tournament_by_id(tournament_id)

    if tournament.status in [TournamentStatus.FINISHED] and not force_restart:
        return

    with transaction.atomic():
        # Validate teams
        qualified_teams = []
        disqualified_teams = []

        registrations = EtheremonDB.TournamentRegistrationTab.objects.filter(
            tournament_id=tournament.id)
        for r in registrations:
            team_info = json.loads(r.team_info)
            team_details = [get_mon_info(mon_id) for mon_id in team_info]
            is_valid, error = ema_battle_manager.is_valid_team(
                team_details, r.player_address)

            for mon in team_details[:3]:
                if not tournament.mon_level_min <= mon[
                        "total_level"] <= tournament.mon_level_max:
                    is_valid = False

            team_info = {
                "player_id": r.player_id,
                "player_address": r.player_address,
                "username":
                user_manager.get_user_name_with_cache(r.player_address),
                "team_info": team_info,
            }

            if not is_valid:
                r.status = TournamentRegistrationStatus.DISQUALIFIED
                r.save()
                disqualified_teams.append(team_info)
            else:
                qualified_teams.append(team_info)

        random.shuffle(qualified_teams)

        current_players = [{
            "team": team,
            "battle_id": -1,
            "children": []
        } for team in qualified_teams]

        while len(current_players) > 1:
            next_round_players = []

            for i in range(0, len(current_players), 2):
                if i == len(current_players) - 1:
                    next_round_players.append(current_players[i])

                else:
                    attacker = current_players[i]
                    defender = current_players[i + 1]

                    result = general_battle_manager.start_battle(
                        attacker["team"]["player_id"],
                        attacker["team"]["player_address"],
                        attacker["team"]["team_info"],
                        defender["team"]["player_id"],
                        defender["team"]["player_address"],
                        defender["team"]["team_info"],
                        battle_type=general_battle_manager.BattleTypes.
                        TOURNAMENT)

                    winner = attacker if result[
                        "result"] == BattleResult.ATTACKER_WIN else defender
                    loser = defender if result[
                        "result"] == BattleResult.ATTACKER_WIN else attacker

                    # Update
                    winner_info = user_manager.get_user_general_info(
                        address=winner["team"]["player_address"])
                    winner_info.tournament_win += 1
                    winner_info.save()

                    loser_info = user_manager.get_user_general_info(
                        address=loser["team"]["player_address"])
                    loser_info.tournament_loss += 1
                    loser_info.save()

                    next_round_players.append({
                        "team": winner["team"],
                        "battle_id": result["battle_id"],
                        "children": [attacker, defender]
                    })

            current_players = next_round_players

        top4 = []
        if current_players and len(current_players) > 0:
            top4.append((current_players[0]["team"]["player_id"],
                         current_players[0]["team"]["player_address"]))

            for t in current_players[0]["children"]:
                if t and t["team"]["player_id"] != top4[0][0]:
                    top4.append(
                        (t["team"]["player_id"], t["team"]["player_address"]))
                    break

            for t1 in current_players[0]["children"]:
                if t1:
                    for t2 in t1["children"]:
                        if t2 and t2["team"]["player_id"] not in [
                                top4[0][0], top4[1][0]
                        ]:
                            top4.append((t2["team"]["player_id"],
                                         t2["team"]["player_address"]))

        reward_data = {}
        prize_pool = tournament.price_pool_emont

        for i, (player_id, player_address) in enumerate(top4):
            reward_data[i] = {
                "player":
                player_id,
                "address":
                player_address,
                "token_reward":
                int(prize_pool * TournamentRewards.TOKENS[i]),
                "mon_reward":
                None
                if len(TournamentRewards.MONS[tournament.tournament_type][i])
                == 0 else random.choice(
                    TournamentRewards.MONS[tournament.tournament_type][i]),
            }

            emont_bonus_manager.add_bonus(
                player_id, {
                    emont_bonus_manager.EmontBonusType.EVENT_BONUS:
                    reward_data[i]["token_reward"]
                })

            if reward_data[i]["mon_reward"]:
                transaction_manager.create_transaction(
                    player_uid=player_id,
                    player_address=player_address,
                    txn_type=TxnTypes.GENERAL_REWARD,
                    txn_info="tournament #%s - rank #%s" %
                    (tournament.id, i + 1),
                    amount_type=TxnAmountTypes.MON,
                    amount_value=reward_data[i]["mon_reward"],
                    status=TxnStatus.INIT,
                )

        # Update tournament
        tournament.status = TournamentStatus.FINISHED
        tournament.result = "" if len(current_players) == 0 else to_json(
            current_players[0])
        tournament.reward = to_json(reward_data)
        tournament.save()
Exemplo n.º 6
0
def claim_quest(quest):
    current_ts = get_timestamp()
    if not (quest.status == quest_config.QuestStatus.TO_CLAIM
            and quest.start_time - 120 <= current_ts <= quest.end_time + 120):
        return None

    with transaction.atomic():
        quest_info = quest_config.QUEST_LIST[quest.quest_id]

        # Claim reward
        if quest.reward_type == RewardTypes.ENERGY:
            ema_energy_manager.add_energy(quest.player_address,
                                          quest.reward_value)
            txn_amount_type = TxnAmountTypes.ENERGY
        elif quest.reward_type == RewardTypes.EMONT:
            emont_bonus_manager.add_bonus(
                quest.player_uid, {EmontBonusType.QUEST: quest.reward_value})
            txn_amount_type = TxnAmountTypes.IN_GAME_EMONT
        elif quest.reward_type == RewardTypes.RANDOM_EMONT:
            quest.reward_value = quest_info['calc_reward_func'](quest,
                                                                current_ts)
            emont_bonus_manager.add_bonus(
                quest.player_uid, {EmontBonusType.QUEST: quest.reward_value})
            txn_amount_type = TxnAmountTypes.IN_GAME_EMONT
        elif quest.reward_type == RewardTypes.HONGBAO:
            user_balance_manager.add_balance_value(quest.player_uid,
                                                   BalanceTypes.HONGBAO,
                                                   quest.reward_value)
            txn_amount_type = TxnAmountTypes.LUNAR_HONGBAO
        else:
            txn_amount_type = TxnAmountTypes.UNDEFINED

        transaction_manager.create_transaction(
            player_uid=quest.player_uid,
            player_address=quest.player_address,
            txn_type=TxnTypes.CLAIM_QUEST,
            txn_info=quest.quest_id,
            amount_type=txn_amount_type,
            amount_value=quest.reward_value,
            status=TxnStatus.FINISHED)

        quest.update_time = current_ts

        if quest.quest_level == len(quest_info[
                "quest_target"]) - 1 and quest.quest_type != QuestTypes.CIRCLE:
            quest.status = QuestStatus.CLOSED
        else:
            if quest.quest_type == QuestTypes.CIRCLE and quest.quest_level == len(
                    quest_info["quest_target"]) - 1:
                # Case CIRCLE QUEST, reset it to level 0
                new_level = 0
                extra_data = json.loads(quest.extra or "{}")
                extra_data["claimed_points"] = extra_data.get(
                    "claimed_points", 0) + quest.quest_target
                quest.extra = json.dumps(extra_data)
            else:
                new_level = quest.quest_level + 1

            quest.quest_level = new_level
            quest.quest_target = quest_info["quest_target"][quest.quest_level]
            quest.reward_type = quest_info["reward_type"][quest.quest_level]
            quest.reward_value = quest_info["reward_value"][quest.quest_level]

            temp = quest_info['update_progress_func'](quest, current_ts)

            quest_progress = temp if not isinstance(temp, tuple) else temp[0]
            quest.quest_progress = min(quest.quest_target, quest_progress)
            quest.status = QuestStatus.TO_DO if quest.quest_progress < quest.quest_target else QuestStatus.TO_CLAIM

            quest_extra_data = None if not isinstance(temp, tuple) else temp[1]
            extra_data = json.loads(quest.extra or "{}")
            extra_data["info"] = quest_extra_data
            quest.extra = json.dumps(extra_data)

        quest.save()

    return quest
Exemplo n.º 7
0
def update_burn_mon_contract():
    infura_client = InfuraClient(INFURA_API_URL)
    current_block = infura_client.getCurrentBlock() - 5

    start_block = ema_settings_manager.get_setting_value(
        EmaSetting.SETTING_CONTRACT_BURN_MON)
    end_block = start_block + SMART_CONTRACT_BLOCK_STEP

    start_time = time.time()
    transaction_list = get_txn_list(EtheremonBurnMonContract.ADDRESS,
                                    start_block, end_block, ETHERSCAN_API_KEY)
    latest_load_block = None
    log.data(
        "start_update_burn_mon_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s",
        current_block, start_block, end_block, len(transaction_list))

    monster_id_set = set()

    for transaction in transaction_list:
        if len(transaction["input"]) < SMART_CONTRACT_METHOD_ID_LENGTH:
            log.warn("invalid_smart_contract_txn|transaction=%s", transaction)
            continue
        if int(transaction.get("isError", 1)) != 0:
            continue
        if int(transaction.get("txreceipt_status")) != 1:
            continue
        if int(transaction["blockNumber"]) > current_block:
            continue

        latest_load_block = int(
            transaction["blockNumber"]) if latest_load_block is None else max(
                latest_load_block, int(transaction["blockNumber"]))
        method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]

        if method_id == BURN_MON_METHOD:
            contract_mon_id_hash = "0x" + transaction[
                "input"][SMART_CONTRACT_METHOD_ID_LENGTH:
                         SMART_CONTRACT_METHOD_ID_LENGTH + 64]
            contract_mon_id = Web3.toInt(hexstr=contract_mon_id_hash)
            contract_burn_id_hash = "0x" + transaction[
                "input"][SMART_CONTRACT_METHOD_ID_LENGTH +
                         64:SMART_CONTRACT_METHOD_ID_LENGTH + 128]
            contract_burn_id = Web3.toInt(hexstr=contract_burn_id_hash)

            mon_id, burn_id = burn_manager.get_mon_id_from_contract_burn_id(
                contract_burn_id)
            burn_request = burn_manager.get_burn_request_by_id(burn_id)

            if not burn_request or burn_request.mon_id != contract_mon_id:
                logging.exception(
                    "burn_mon_failed|contract_burn_id=%s,txn_hash=%s",
                    contract_burn_id, transaction["hash"])
                continue

            if burn_request.status in [BurnStatus.FINISHED, BurnStatus.FAILED]:
                logging.exception(
                    "burn_already_finished|contract_burn_id=%s,txn_hash=%s",
                    contract_burn_id, transaction["hash"])
                continue

            try:
                with transaction.atomic():
                    player_uid = user_manager.get_uid_by_address_default_0(
                        burn_request.player_address)

                    if burn_request.reward_value > 0:
                        # Only if there is reward
                        if burn_request.reward_type == BurnRewardTypes.ENERGY:
                            ema_energy_manager.add_energy(
                                burn_request.player_address,
                                burn_request.reward_value)
                        elif burn_request.reward_type == BurnRewardTypes.IN_GAME_EMONT:
                            emont_bonus_manager.add_bonus(
                                player_uid, {
                                    EmontBonusType.EVENT_BONUS:
                                    burn_request.reward_value
                                })

                        transaction_manager.create_transaction(
                            player_uid=player_uid,
                            player_address=burn_request.player_address,
                            txn_type=TxnTypes.BURN_MON_REWARD,
                            txn_info="mon %s" % burn_request.mon_id,
                            amount_type=TxnAmountTypes.IN_GAME_EMONT
                            if burn_request.reward_type
                            == BurnRewardTypes.IN_GAME_EMONT else
                            TxnAmountTypes.ENERGY,
                            amount_value=burn_request.reward_value,
                            status=TxnStatus.FINISHED,
                            txn_hash=transaction["hash"])

                        # 300 EMONT BONUS
                        # if burn_request.mon_level >= 30 and randint(1, 100) <= 3:
                        if randint(1, 100) <= 3:
                            additional_bonus = 500

                            emont_bonus_manager.add_bonus(
                                player_uid,
                                {EmontBonusType.EVENT_BONUS: additional_bonus})

                            transaction_manager.create_transaction(
                                player_uid=player_uid,
                                player_address=burn_request.player_address,
                                txn_type=TxnTypes.BURN_MON_REWARD_BONUS,
                                txn_info="mon %s" % burn_request.mon_id,
                                amount_type=TxnAmountTypes.IN_GAME_EMONT,
                                amount_value=additional_bonus,
                                status=TxnStatus.FINISHED,
                                txn_hash=transaction["hash"])

                    burn_request.status = BurnStatus.FINISHED
                    burn_request.save()
            except:
                logging.exception(
                    "burn_mon_failed|contract_burn_id=%s,txn_hash=%s",
                    contract_burn_id, transaction["hash"])
                continue

    record_block = latest_load_block + 1 if latest_load_block is not None else end_block + 1
    record_block = min(record_block, current_block)

    ema_settings_manager.set_or_create_setting(
        setting_id=EmaSetting.SETTING_CONTRACT_BURN_MON,
        name="burn mon contract",
        value=record_block)
    elapsed = time.time() - start_time
    if elapsed < 5:
        time.sleep(5 - elapsed)
    log.data(
        "end_update_burn_mon_contract|record_block=%s,total_txn=%s,total_monster=%s,elapsed=%s",
        record_block, len(transaction_list), len(monster_id_set), elapsed)