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 )
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)
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, })
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()
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
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)