2022-04-22 00:12:46 +08:00

260 lines
7.8 KiB
JavaScript

const app = require('j7/app');
const utils = require('j7/utils');
const bcutils = require('j7/bcutils');
const log = require('j7/log');
const event = require('j7/event');
const serviceFactory = require('./factory');
const metaFactory = require('../metadata/factory');
const bc = require('../blockchain');
const C = require('../C');
const LIMIT_COUNT = 100;
class EventCenter {
async init() {
this.lastIdx = 0;
this.pendingConfirmOwnerHash = {};
const {err, conn} = await app.getDbConn('MarketDb0');
if (err) {
throw 'db error:' + err;
}
this.conn = conn;
event.addListener(C.DESTORY_EXEC_CONFIRM_OWNER_EVENT, (tokenId) => {
log.info('destory:' + tokenId);
try {
if (utils.getVal(this.pendingConfirmOwnerHash, tokenId)) {
delete this.pendingConfirmOwnerHash[tokenId];
}
} catch(err) {
log.error('destory confirm owner:' + err);
}
});
this.confirmOwner();
this.pullNftTransferEvent();
this.pullBoxOpenedEvent();
}
async addConfirmOwnerRequest(tokenId) {
const pendingRequest = utils.getVal(this.pendingConfirmOwnerHash, tokenId);
if (!pendingRequest) {
const newRequest = new serviceFactory.create('ExecConfirmOwner', null);
this.pendingConfirmOwnerHash[tokenId] = newRequest;
newRequest.init(tokenId);
return;
} else {
pendingRequest.addTryCount();
}
}
async confirmOwner() {
let maxIdx = 0;
while (true) {
{
const {err, rows} = await this.conn.execQuery(
'SELECT * FROM t_nft_transfer WHERE `idx` > ? AND ' +
'`owner_confirmed` = 0 LIMIT ' + LIMIT_COUNT,
[this.lastIdx]);
if (!err) {
for (let i in rows) {
const row = rows[i];
this.addConfirmOwnerRequest(row['token_id']);
if (row['idx'] > this.lastIdx) {
this.lastIdx = row['idx'];
}
}
if (rows.length < 1 && this.lastIdx + LIMIT_COUNT < maxIdx) {
this.lastIdx += LIMIT_COUNT;
continue;
}
}
}
{
const {err, row} = await this.conn.execQueryOne(
'SELECT max(idx) max_idx FROM t_nft_transfer', []);
if (!err && row['max_idx'] != null) {
maxIdx = row['max_idx'];
}
}
while (Object.keys(this.pendingConfirmOwnerHash).length > 50) {
await utils.sleep(1000 + utils.randRange(500, 1500));
}
await utils.sleep(2000 + utils.randRange(500, 1500));
}
}
async pullNftTransferEvent() {
const instances = [
{
'name': 'heroInstance',
'last_block_number': 0,
},
{
'name': 'equipInstance',
'last_block_number': 0,
},
{
'name': 'chipInstance',
'last_block_number': 0,
},
{
'name': 'luckboxInstance',
'last_block_number': 0,
}
];
while (true) {
for (let i in instances) {
const instance = instances[i];
console.log(instance);
const events = await bc[instance['name']].getPastEvents(
'Transfer',
{
fromBlock: instance['last_block_number'] + 1,
//toBlock: 'lea',
},
);
for (let ii in events) {
const event = events[ii];
if (event['blockNumber'] > instance['last_block_number']) {
instance['last_block_number'] = event['blockNumber']
}
const {err, row} = await this.conn.ormSelectOne(
't_nft_transfer',
[
['txhash', event['transactionHash']],
['log_index', event['logIndex']],
]
);
if (!err) {
if (!row) {
const returnValues = event['returnValues'];
await this.conn.insert(
't_nft_transfer',
[
['token_id', returnValues['tokenId']],
['token_type', 0],
['txhash', event['transactionHash']],
['block_number', event['blockNumber']],
['log_index', event['logIndex']],
['_from', bcutils.toNormalAddress(returnValues['from'])],
['_to', bcutils.toNormalAddress(returnValues['to'])],
['raw_data', utils.jsonEncode(event)],
['createtime', utils.getUtcTime()],
['modifytime', utils.getUtcTime()],
]
);
}
}
}
}//end for
await utils.sleep(2000 + utils.randRange(500, 1500));
}
}
async pullBoxOpenedEvent() {
return;
const instance = {
'name': 'boxproxyInstance',
'last_block_number': 0,
};
while (true) {
const events = await bc[instance['name']].getPastEvents(
'BoxOpened',
{
fromBlock: instance['last_block_number'] + 1,
//toBlock: 'lea',
},
);
for (let ii in events) {
const event = events[ii];
if (event['blockNumber'] > instance['last_block_number']) {
instance['last_block_number'] = event['blockNumber']
}
const {err, row} = await this.conn.ormSelectOne(
't_boxopened_event',
[
['txhash', event['transactionHash']],
['log_index', event['logIndex']],
]
);
if (!err) {
if (!row) {
const blockNumber = event['blockNumber'];
const returnValues = event['returnValues'];
const fieldList = [
['box_token_id', returnValues['boxId']],
['txhash', event['transactionHash']],
['block_number', blockNumber],
['log_index', event['logIndex']],
['_to', bcutils.toNormalAddress(returnValues['to'])],
['raw_data', utils.jsonEncode(event)],
['createtime', utils.getUtcTime()],
['modifytime', utils.getUtcTime()],
];
for (let iii = 0; iii < 3; ++iii) {
const id = returnValues['ids'][iii];
const type = returnValues['types'][iii];
if (id != '0') {
fieldList.push(
['token_id' + (iii + 1), id],
);
fieldList.push(['token_type' + (iii + 1), type]),
await this.mintNft(bcutils.toNormalAddress(returnValues['to']), blockNumber, id, type);
}
}
await this.conn.insert(
't_boxopened_event',
fieldList
);
}
}
}
console.log(events);
await utils.sleep(2000 + utils.randRange(500, 1500));
}
}
async mintNft(owner, blockNumber, tokenId, tokenType) {
const {err, row} = await this.conn.ormSelectOne(
't_nft',
[
['token_id', tokenId],
]
);
if (!err) {
if (!row) {
const itemMeta = metaFactory.getMetaByKey('Item', 110001);
if (!itemMeta) {
return;
}
const nftItemId = itemMeta.randLuckBox(tokenType);
if (nftItemId > 0) {
const nowTime = utils.getUtcTime();
const fieldList = [
['token_id', tokenId],
['token_type', tokenType],
['item_id', nftItemId],
['tags', tokenType == bcutils.HERO_TYPE ? '1' : 0],
['game_id', 2006],
['owner_address', bcutils.toNormalAddress(owner)],
['creator_address', bcutils.toNormalAddress(owner)],
['confirm_block_number', blockNumber],
['createtime', nowTime],
['modifytime', nowTime],
];
await this.conn.insert(
't_nft',
fieldList
);
}
}
}
}
}
module.exports = EventCenter;