def get_or_create_burn_request(player_address, mon_id, mon_level=1, mon_exp=1, amount_type=BurnRewardTypes.UNDEFINED, amount_value=0, status=BurnStatus.INIT): burn_request = get_burn_request_by_mon(player_address, mon_id)\ .filter(status__in=[BurnStatus.INIT, BurnStatus.PENDING])\ .first() if burn_request: if burn_request.mon_level != mon_level or burn_request.mon_exp != mon_exp: burn_request.mon_level = mon_level burn_request.mon_exp = mon_exp burn_request.save() return burn_request burn_request = EtheremonDB.BurnMonTab( player_address=player_address, mon_id=mon_id, mon_level=mon_level, mon_exp=mon_exp, amount_type=amount_type, amount_value=amount_value, status=status, create_time=get_timestamp(), update_time=get_timestamp(), ) burn_request.save() return burn_request
def create_transaction(player_uid, player_address, txn_type, txn_info, amount_type, amount_value, status=TxnStatus.INIT, txn_hash=None, extra=None): txn = EtheremonDB.TransactionTab( player_uid=player_uid, player_address=player_address, txn_type=txn_type, txn_info=txn_info, txn_hash=txn_hash, status=status, amount_type=amount_type, amount_value=round(amount_value, 4), extra=extra if extra is None else json.dumps(extra), create_time=get_timestamp(), update_time=get_timestamp(), ) txn.save() return txn
def crawl_adventure_presale(): infura_client = InfuraClient(INFURA_API_URL) adventure_presale_contract = infura_client.getAdventurePresaleContract() current_ts = get_timestamp() site_id_index = 1 while site_id_index <= 54: site_item_index = 0 while site_item_index < 10: try: (bidder, bid_id, site_id, amount, bid_time ) = adventure_presale_contract.call().getBidBySiteIndex( site_id_index, site_item_index) if bid_id == 0: log.warn( "query_adventure_presale_invalid|site_id=%s,site_index=%s", site_id_index, site_item_index) time.sleep(3) continue except Exception as error: logging.exception( "query_adventure_presale_exception|site_id=%s,site_index=%s", site_id_index, site_item_index) time.sleep(3) continue bidder = bidder.lower() record = EtheremonDB.EmaAdventurePresaleTab.objects.filter( bid_id=bid_id).first() if record: record.site_id = site_id record.bid_id = bid_id record.site_index = site_item_index record.bidder = bidder record.bid_amount = amount record.bid_time = bid_time else: record = EtheremonDB.EmaAdventurePresaleTab( site_id=site_id, site_index=site_item_index, bid_id=bid_id, bidder=bidder, bid_amount=amount, bid_time=bid_time, token_id=0, update_time=current_ts) log.data( "adventure_presale_query|site_id=%s,site_index=%s,bid_id=%s", site_id_index, site_item_index, bid_id) record.save() site_item_index += 1 site_id_index += 1
def initialize_energy_if_not_exist(trainer_address, init_amount=10): record = EtheremonDB.EmaPlayerEnergyTab.objects.filter(trainer=trainer_address).first() current_ts = get_timestamp() if not record: record = EtheremonDB.EmaPlayerEnergyTab( trainer=trainer_address, init_amount=init_amount, free_amount=0, paid_amount=0, invalid_amount=0, consumed_amount=0, last_claim_time=0, create_time=current_ts, update_time=current_ts ) record.save() return record
def update_adventure_nft_contract(): infura_client = InfuraClient(INFURA_API_URL) current_block = infura_client.getCurrentBlock() - 2 start_block = ema_settings_manager.get_setting_value(EmaSetting.SETTING_CONTRACT_ADVENTURE_ITEM) end_block = start_block + SMART_CONTRACT_BLOCK_STEP start_time = time.time() event_list = get_event_list(EtheremonAdventureItemContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY, TOPIC_TRANSFER) if event_list is None: return log.data("start_update_adventure_nft_contract|current_block=%s,start_block=%s,end_block=%s,len_event=%s", current_block, start_block, end_block, len(event_list)) latest_load_block = start_block token_id_set = set() token_id_address_dict = {} from_address_set = set() for event in event_list: latest_load_block = max(latest_load_block, int(event["blockNumber"], 16)) if latest_load_block > current_block: return token_id_hash = event["topics"][3] token_id = Web3.toInt(hexstr=token_id_hash) token_id_set.add(token_id) from_address = '0x' + event["topics"][1][26:].lower() token_address = '0x' + event["topics"][2][26:].lower() from_address_set.add(from_address) if token_id in token_id_address_dict: token_id_address_dict[token_id].add(token_address) else: token_id_address_dict[token_id] = set([token_address]) log.info("scan_adventure_event|txn_hash=%s,token_id=%s,target_address=%s,from_address=%s", event["transactionHash"], token_id, token_address, from_address) current_ts = get_timestamp() if token_id_set: adventure_item_contract = infura_client.getAdventureItemContract() for token_id in token_id_set: try: owner = adventure_item_contract.call().ownerOf(token_id) except Exception as error: log.info("error_owner_token|token_id=%s", token_id) owner = EMPTY_ADDRESS owner = owner.lower() if owner not in token_id_address_dict[token_id]: # Case current owner is different from the old transaction => ignore log.warn("adventure_item_owner_invalid|token_id=%s,owner=%s,owner_set=%s", token_id, owner, token_id_address_dict[token_id]) continue (item_class, item_value) = adventure_item_contract.call().getItemInfo(token_id) if item_class == 0: log.warn("adventure_item_class_invalid|token_id=%s,item_class=%s,item_value=%s", token_id, item_class, item_value) return token_record = EtheremonDB.EmaAdventureItemTab.objects.filter(token_id=token_id).first() if token_record: token_record.owner = owner token_record.class_id = item_class token_record.value = item_value token_record.update_time = current_ts else: token_record = EtheremonDB.EmaAdventureItemTab( token_id=token_id, owner=owner, class_id=item_class, value=item_value, update_time=current_ts ) token_record.save() # update claim if token_id < 1081: if token_id % 10 == 0: site_id = token_id / 10 site_index = 9 else: site_id = token_id / 10 + 1 site_index = token_id % 10 - 1 EtheremonDB.EmaAdventurePresaleTab.objects.filter(site_id=site_id).filter(site_index=site_index).update(token_id=token_id) # sync player data if from_address_set: log.info("update_adventure_nft_contract|sender_len=%s,latest_load_block=%s", len(from_address_set), latest_load_block) data_contract = infura_client.getDataContract() for player in from_address_set: result = _sync_player_dex(data_contract, player, None, True) if result is False: log.warn("sync_player_fail|player=%s", player) return log.info("contract_adventure_nft_sync_player|sync_player=%s,block=%s", player, current_block) record_block = latest_load_block if len(token_id_set) > 0: record_block += 1 if record_block > current_block: record_block = current_block ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_ADVENTURE_ITEM, record_block) elapsed = time.time() - start_time if elapsed < 5: time.sleep(5-elapsed) log.data("end_update_adventure_item_contract|record_block=%s,total_txn=%s,total_token=%s,elapsed=%s", record_block, len(event_list), len(token_id_set), elapsed)
def cal_txn(contract_address, default_block=START_BLOCK): total_count = 0 start_block = EtheremonDB.RevenueTxnTab.objects.filter( contract_address=contract_address).all().aggregate(Max('block_number')) if not start_block["block_number__max"]: start_block = default_block[contract_address] else: start_block = start_block["block_number__max"] print start_block while True: end_block = start_block + SMART_CONTRACT_BLOCK_STEP time.sleep(3) transaction_list = get_txn_list(contract_address, start_block, end_block, ETHERSCAN_API_KEYS["cron_3"]) if transaction_list is None: break if len(transaction_list) == 0: break new_row = 0 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 block_number = int(transaction["blockNumber"]) start_block = max(start_block, block_number) eth_amount = long(transaction["value"]) if eth_amount == 0: continue txn_time = int(transaction["timeStamp"]) catch_date_str = _getDate(txn_time) catch_date_int = _getDateInInteger(txn_time) eth_amount = float(eth_amount * 1.0 / (10**18)) if catch_date_str not in ETH_PRICE_DICT: #print "--- missing ETH price:", catch_date_str #break usd_amount = 0 else: usd_amount = float(eth_amount * ETH_PRICE_DICT[catch_date_str]) method_id = str(transaction["input"] [0:SMART_CONTRACT_METHOD_ID_LENGTH]).lower() sender = str(transaction["from"]).lower() txn_hash = str(transaction["hash"]).lower() current_record = EtheremonDB.RevenueTxnTab.objects.filter( txn_hash=txn_hash).first() if not current_record: EtheremonDB.RevenueTxnTab(contract_address=contract_address, method_id=method_id, txn_hash=txn_hash, sender=sender, eth_amount=eth_amount, usd_amount=usd_amount, block_number=block_number, create_date=catch_date_int, timestamp=txn_time).save() new_row += 1 total_count += 1 if new_row == 0: break print "query:contract=%s,total_added=%s,block=%s" % ( contract_address, total_count, start_block)
def _sync_monster_id(data_contract, monster_id, transform_contract=None, base_stats_refresh=False): add_count = 0 update_count = 0 # check monster is existed or not monster_record = EtheremonDB.EmaMonsterDataTab.objects.filter(monster_id=monster_id).first() if monster_record and monster_record.class_id == 21: # skip non important monster return True, 0, 0 (monster_return_id, class_id, owner_address, exp, create_index, last_claim_index, monster_create_time) = data_contract.call().getMonsterObj(monster_id) if int(class_id) == 0: # Bug, break log.error('update_ema_monster_error|monster_id=%s', monster_id) return False, 0, 0 log.info("sync_monster_id|contract_data|monster_id=%s,owner_address=%s,exp=%s", monster_id, owner_address, owner_address) owner_address = owner_address.lower() name = data_contract.call().getMonsterName(monster_id) name = name.encode("latin1").decode("utf8").strip() name = (name[:100] + '..') if len(name) > 100 else name egg_bonus = None if transform_contract and class_id <= 24: egg_bonus = transform_contract.call().getBonusEgg(monster_id) current_ts = get_timestamp() exp_flag = False trainer_flag = None # update information if monster_record: if egg_bonus is None: egg_bonus = monster_record.egg_bonus if base_stats_refresh: base_stats = [] for index in xrange(0, 6): stat_value = data_contract.call().getElementInArrayType(DataArrayType.STAT_BASE, monster_id, index) base_stats.append(stat_value) # if 0 in base_stats: # log.error('update_ema_monster_error|monster_id=%s,base_stats=%s', monster_id, base_stats) # return False, 0, 0 monster_record.b0 = base_stats[0] monster_record.b1 = base_stats[1] monster_record.b2 = base_stats[2] monster_record.b3 = base_stats[3] monster_record.b4 = base_stats[4] monster_record.b5 = base_stats[5] monster_record.save() # Nothing to update if monster_record.trainer == owner_address \ and monster_record.exp == exp \ and monster_record.name == name \ and monster_record.last_claim_index == last_claim_index \ and monster_record.egg_bonus == egg_bonus: return True, 0, 0 # update exp if monster_record.exp != exp: exp_flag = True monster_record.exp = exp # get bp stats, bp, level = get_stats( monster_record.class_id, monster_record.exp, [monster_record.b0, monster_record.b1, monster_record.b2, monster_record.b3, monster_record.b4, monster_record.b5] ) monster_record.bp = bp # Update rank team if necessary if monster_record.trainer != owner_address: trainer_flag = monster_record.trainer monster_record.egg_bonus = egg_bonus monster_record.trainer = owner_address monster_record.name = name monster_record.last_claim_index = last_claim_index monster_record.update_time = current_ts monster_record.save() log.info("update_ema_monster_info|monster_id=%s", monster_id) update_count += 1 dcl_manager.dcl_update_transferred_mon(monster_id, owner_address) else: # Case new mon exp_flag = True base_stats = [] for index in xrange(0, 6): stat_value = data_contract.call().getElementInArrayType(DataArrayType.STAT_BASE, monster_id, index) base_stats.append(stat_value) if 0 in base_stats: log.error('update_ema_monster_error|monster_id=%s,base_stats=%s', monster_id, base_stats) return False, 0, 0 # get bp stats, bp, level = get_stats( class_id, exp, [base_stats[0], base_stats[1], base_stats[2], base_stats[3], base_stats[4], base_stats[5]] ) if egg_bonus is None: egg_bonus = 0 monster_record = EtheremonDB.EmaMonsterDataTab( monster_id=monster_id, class_id=class_id, trainer=owner_address, name=name, exp=exp, b0=base_stats[0], b1=base_stats[1], b2=base_stats[2], b3=base_stats[3], b4=base_stats[4], b5=base_stats[5], bp=bp, egg_bonus=egg_bonus, create_index=create_index, last_claim_index=last_claim_index, create_time=monster_create_time, update_time=current_ts ) monster_record.save() log.info("add_ema_monster_info|monster_id=%s", monster_id) add_count += 1 # update exp if exp_flag: monster_stats = [monster_record.b0, monster_record.b1, monster_record.b2, monster_record.b3, monster_record.b4, monster_record.b5] status = EmaMonsterStatus.Normal if monster_record.trainer == EMPTY_ADDRESS: status = EmaMonsterStatus.Deleted update_ema_monster_bp(monster_id, class_id, monster_stats, monster_record.exp, status) # Update old_player_rank if trainer_flag: ema_player_manager.try_disband_team(trainer_flag) log.info("sync_monster_id|monster_id=%s,exp=%s,class_id=%s", monster_id, exp, class_id) return True, add_count, update_count
def create_or_update_quest(player_uid, player_address, quest_id, quest): current_ts = get_timestamp() today_start_time = get_start_time_of_the_day(current_ts) today_end_time = get_end_time_of_the_day(current_ts) # Get quest info quest_info = quest_config.QUEST_LIST[quest_id] quest_start_time = quest_info.get("start_time", 0) quest_end_time = quest_info.get("end_time", INFINITY_FUTURE) is_daily_quest = quest_info[ 'quest_type'] == QuestTypes.DAILY or quest_info.get('is_daily', False) # Case daily quest reset if quest and is_daily_quest: if current_ts > quest.end_time: quest.start_time = max(quest_start_time, today_start_time) quest.end_time = min(quest_end_time, today_end_time) quest.status = QuestStatus.TO_DO quest.quest_level = 0 quest.quest_target = quest_info['quest_target'][0] quest.reward_type = quest_info['reward_type'][0] quest.reward_value = quest_info['reward_value'][0] # Case claimed / finished quest if quest and quest.status != QuestStatus.TO_DO: return quest # Case new quest if quest is None: quest = EtheremonDB.QuestTab( player_uid=player_uid, player_address=player_address, quest_id=quest_id, quest_type=quest_info['quest_type'], quest_level=0, quest_name=quest_info['quest_name'], quest_target=quest_info['quest_target'][0], quest_progress=0, reward_type=quest_info['reward_type'][0], reward_value=quest_info['reward_value'][0], status=QuestStatus.TO_DO, start_time=quest_start_time if not is_daily_quest else max( quest_start_time, today_start_time), end_time=quest_end_time if not is_daily_quest else min( quest_end_time, today_end_time), last_check=0, create_time=current_ts, extra="{}", ) # Update progress 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) # Ready to claim if quest.quest_progress == quest.quest_target: quest.status = 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.last_check = current_ts quest.update_time = current_ts quest.save() return quest
def crawl_txn(): start_block = EtheremonDB.PartnerMchPresaleTab.objects.all().aggregate( Max('latest_block_number')) if not start_block["latest_block_number__max"]: start_block = START_BLOCK else: start_block = start_block["latest_block_number__max"] old_block = 0 while True: end_block = start_block + SMART_CONTRACT_BLOCK_STEP time.sleep(3) transaction_list = get_txn_list(SMART_CONTRACT_ADDRESS, start_block, end_block, ETHERSCAN_API_KEYS["cron_3"]) if transaction_list is None: break if len(transaction_list) == 0: break 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 block_number = int(transaction["blockNumber"]) start_block = max(start_block, block_number) eth_amount = long(transaction["value"]) if eth_amount == 0: continue txn_time = int(transaction["timeStamp"]) eth_amount = float(eth_amount * 1.0 / (10**18)) sender = str(transaction["from"]).lower() txn_hash = str(transaction["hash"]).lower() current_record = EtheremonDB.PartnerMchPresaleTab.objects.filter( player=sender).first() if not current_record: # check etheremon player mch_flag = MCHFlag.FLAG_NONE country = "" etheremon_user = EtheremonDB.UserTab.objects.filter( address=sender).first() if etheremon_user: mch_flag = MCHFlag.FLAG_ETHEREMON_PLAYER country = etheremon_user.country else: if EtheremonDB.EmaMonsterDataTab.objects.filter( trainer=sender).count() > 0: mch_flag = MCHFlag.FLAG_ETHEREMON_PLAYER EtheremonDB.PartnerMchPresaleTab( player=sender, amount=eth_amount, flag=mch_flag, country=country, txn_count=1, latest_block_number=block_number).save() else: if current_record.latest_block_number >= block_number: continue current_record.amount += eth_amount current_record.txn_count += 1 current_record.latest_block_number = block_number current_record.save() if start_block == old_block: break old_block = start_block