listMySelledNfts($account, $type)); foreach ($rows as &$row) { $nftDb = Nft::findNftByOwner($account, $row['token_id']); if (empty($nftDb)) { $nftDb = Nft::getNft($row['token_id']); } // $row['info'] = Nft::toDto($nftDb); // $row['detail'] = Hero::toDtoInfo(Hero::findByTokenId2($row['token_id'])); // if (in_array($row['info']['info']['job'], $job) == false) continue; // if ($row['detail']['hero_lv'] < $lv) continue; // if ($row['detail']['quality'] < $quality) continue; // if ($row['detail']['hero_tili'] < $durability) continue; if (count($search) > 0) { $searchLower = array_map('strtolower', $search); if (!(in_array(strtolower($row['detail']['hero_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue; } // $row['detail'] = $this->appendChipsInfo($row['detail']); array_push($nfts, $row); } switch ($order_method) { case 1: usort($nfts, $sortByLevel); break; case 2: usort($nfts, $sortByTili); break; case 3: usort($nfts, $sortByStar); break; } } break; case Nft::HERO_TYPE: { $rows = Nft::getNftListByType($account, $type); $rows = array_merge($rows, $this->listMySelledNfts($account, $type)); foreach ($rows as &$row) { $nftDb = Nft::findNftByOwner($account, $row['token_id']); if (empty($nftDb)) { $nftDb = Nft::getNft($row['token_id']); } $row['info'] = Nft::toDto($nftDb); $row['detail'] = Hero::toDtoInfo(Hero::findByTokenId2($row['token_id'])); if (!empty($job)) { if (in_array($row['info']['info']['job'], $job) == false) continue; } if ($row['detail']['hero_lv'] < $lv) continue; if ($row['detail']['quality'] < $quality) continue; if ($row['detail']['hero_tili'] < $durability) continue; if (count($search) > 0) { $searchLower = array_map('strtolower', $search); if (!(in_array(strtolower($row['detail']['hero_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue; } $row['detail'] = $this->appendChipsInfo($row['detail']); array_push($nfts, $row); } switch ($order_method) { case 1: usort($nfts, $sortByLevel); break; case 2: usort($nfts, $sortByTili); break; case 3: usort($nfts, $sortByStar); break; } } break; case Nft::EQUIP_TYPE: { $rows = Nft::getNftListByType($account, $type); $rows = array_merge($rows, $this->listMySelledNfts($account, $type)); foreach ($rows as &$row) { $nftDb = Nft::findNftByOwner($account, $row['token_id']); if (empty($nftDb)) { $nftDb = Nft::getNft($row['token_id']); } $row['info'] = Nft::toDto($nftDb); $row['detail'] = Gun::toDtoInfo(Gun::findByTokenId2($row['token_id'])); if ($row['detail']['gun_lv'] < $lv) continue; if ($row['detail']['quality'] < $quality) continue; if ($row['detail']['durability'] < $durability) continue; if (count($search) > 0) { $searchLower = array_map('strtolower', $search); if (!(in_array(strtolower($row['detail']['gun_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue; } $row['detail'] = $this->appendChipsInfo($row['detail']); array_push($nfts, $row); } switch ($order_method) { case 1: usort($nfts, $sortByGunLv); break; case 2: usort($nfts, $sortByDurability); break; case 3: usort($nfts, $sortByStar); break; } } break; case Nft::CHIP_TYPE: { $rows = Nft::getNft1155List($account, $type); $rows = array_merge($rows, $this->listMySelledNfts($account, $type)); foreach ($rows as &$row) { $row['detail'] = Chip::toDto(Chip::getChipByTokenId($row['token_id'])); if (!in_array($row['detail']['chip_type'], $job)) continue; if ($row['detail']['chip_grade'] < $lv) continue; if (count($search) > 0) { $searchLower = array_map('strtolower', $search); if (!(in_array(strtolower($row['detail']['chip_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue; } array_push($nfts, $row); } switch ($order_method) { case 1: usort($nfts, $sortByGrade); break; case 2: usort($nfts, $sortByPower); break; } } break; case Nft::FRAGMENT_TYPE: { $rows = Nft::getNft1155List($account, $type); $rows = array_merge($rows, $this->listMySelledNfts($account, $type)); foreach ($rows as &$row) { $nftDb = Nft::findNftByOwner($account, $row['token_id']); if (empty($nftDb)) { $nftDb = Nft::getNft($row['token_id']); } $row['detail'] = $this->getNftGameData($nftDb); if (!in_array($row['detail']['type'], $job)) continue; if (count($search) > 0) { $searchLower = array_map('strtolower', $search); if (!(in_array(strtolower($row['detail']['name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue; } array_push($nfts, $row); } usort($nfts, $sortByTokenId); } break; default: { } } return $nfts; } public function listSellNfts() { $account = strtolower(getReqVal('account', '')); $token = getReqVal('token', ''); $start = getReqVal('start', 0); $page_size = getReqVal('page_size', 10); $order_method = getReqVal('order_method', 0); $order_asc = getReqVal('order_asc', 1); $type = getReqVal('type', 1); $job_filters = getReqVal('job_filters', ''); $job_filter_array = explode('|', $job_filters); $search_filters = getReqVal('search_filters', ''); error_log('search_filters:' . $search_filters); if ($search_filters != '') { $search_filter_array = explode('|', $search_filters); } else { $search_filter_array = array(); } $lv_filter = getReqVal('lv_filter', 0); $quality_filter = getReqVal('quality_filter', 0); $durability_filter = getReqVal('durability_filter', 0); $amount_filter = getReqVal('amount_filter', 0); $amount_filter_array = explode('|', $amount_filter); $price_filter = getReqVal('price_filter', ''); $price_filter_array = explode('|', $price_filter); $job_filter_fn = function ($f) { $str = ''; $arr = array(); foreach ($f as $v) { if (!empty($v)) { array_push($arr, 'c_job=\'' . $v . '\' '); } } if (count($arr) > 0) { $str = implode('OR ', $arr); $str = 'AND (' . $str . ') '; } return $str; }; $price_filter_fn = function ($f) { if (count($f) == 2) { $low = $f[0]; $top = $f[1]; return 'AND s_price>=' . $low . ' AND s_price<=' . $top . ' '; } return ''; }; $amount_filter_fn = function ($f) { if (count($f) == 2) { $low = $f[0]; $top = $f[1]; return 'AND amount>=' . $low . ' AND amount<=' . $top . ' '; } return ''; }; $lv_filter_fn = function ($f) { $f = (int) $f; return 'AND c_lv>=' . $f . ' '; }; $quality_filter_fn = function ($f) { $f = (int) $f; return 'AND c_quality>=' . $f . ' '; }; $durability_filter_fn = function ($f) { $f = (int) $f; return 'AND c_durability>=' . $f . ' '; }; $search_filter_fn = function ($f) { $str = ''; error_log('search_filter ' . json_encode($f)); $arr_options = array(); foreach ($f as $v) { if (!empty($v)) { array_push($arr_options, 'c_name=\'' . $v . '\' OR token_id=\'' . $v . '\' '); } } error_log('$$search_filter ' . json_encode($arr_options)); if (count($arr_options) > 0) { $str = implode('OR ', $arr_options); $str = 'AND (' . $str . ') '; } return $str; }; $order_fn = function ($method, $asc) { switch ($method) { case 2: return 'ORDER BY s_price ' . ($asc == 0 ? 'ASC' : 'DESC') . ' '; break; case 3: return 'ORDER BY c_quality ' . ($asc == 0 ? 'ASC' : 'DESC') . ' '; break; case 4: return 'ORDER BY c_lv ' . ($asc == 0 ? 'ASC' : 'DESC') . ' '; break; case 5: return 'ORDER BY c_durability ' . ($asc == 0 ? 'ASC' : 'DESC') . ' '; break; // 所有其他不正常的排序都执行最新上架 case 1: default: return 'ORDER BY createtime ' . ($asc == 0 ? 'ASC' : 'DESC') . ' '; break; } return ''; }; $conn = myself()->_getMysql(''); $counts = $conn->execQuery( 'SELECT count(*) as count FROM t_market_store ' . 'WHERE token_type=:token_type AND status=0 ' . $job_filter_fn($job_filter_array) . $lv_filter_fn($lv_filter) . $quality_filter_fn($quality_filter) . $durability_filter_fn($durability_filter) . $price_filter_fn($price_filter_array) . $amount_filter_fn($amount_filter_array) . $search_filter_fn($search_filter_array) . $order_fn($order_method, $order_asc), array( ':token_type' => $type, ) ); $total = $counts[0]['count']; $page_end = $start + $page_size; if ($page_end > $total) { $page_end = $total; $start = $total - 1; $start = intval($start / $page_size) * $page_size; if ($start < 0) $start = 0; } $rows = $conn->execQuery( 'SELECT * FROM t_market_store ' . 'WHERE token_type=:token_type AND status=0 ' . $job_filter_fn($job_filter_array) . $lv_filter_fn($lv_filter) . $quality_filter_fn($quality_filter) . $durability_filter_fn($durability_filter) . $price_filter_fn($price_filter_array) . $amount_filter_fn($amount_filter_array) . $search_filter_fn($search_filter_array) . $order_fn($order_method, $order_asc) . 'LIMIT ' . $start . ',' . $page_size, array( ':token_type' => $type, ) ); $nfts = array(); for ($x = $start; $x < $page_end; $x++) { $row = $rows[$x % $page_size]; $nftDb = Nft::getNft($row['token_id']); if (!$nftDb) { $nftDb = Nft::findNftByOwner($account, $row['token_id']); // 0x768b5faed6dc69816f33377d214ffaf00dcdd0cf if (!$nftDb) { $nftDb = Nft::findNftByOwner('0xfc628dd79137395f3c9744e33b1c5de554d94882', $row['token_id']); if (!$nftDb) { if ($row['item_id']) { } else { myself()->_rspErr(1, 'nft not exists'); return; } } } } $row['info'] = $nftDb ? Nft::toDto($nftDb) : null; $row['detail'] = $nftDb ? $this->getNftGameData($nftDb) : null; array_push($nfts, $row); } $this->_rspData(array( "total" => $total, "start" => $start, "page_size" => $page_size, 'nfts' => $nfts, )); } public function listMyNfts() { $account = strtolower(getReqVal('account', '')); $token = getReqVal('token', ''); $start = getReqVal('start', 0); $page_size = getReqVal('page_size', 10); $order_method = getReqVal('order_method', 0); $order_asc = getReqVal('order_asc', 1); $type = getReqVal('type', 1); $job_filters = getReqVal('job_filters', ''); $address = $this->_getAddress(); if ($address != $account) { $this->_rspErr(1, 'account not match'); return; } if (empty($job_filters)) { $job_filter_array = array(); } else { $job_filter_array = explode('|', $job_filters); } $search_filters = getReqVal('search_filters', ''); error_log('search_filters:' . $search_filters); if ($search_filters != '') { $search_filter_array = explode('|', $search_filters); } else { $search_filter_array = array(); } $lv_filter = getReqVal('lv_filter', 0); $quality_filter = getReqVal('quality_filter', 0); $durability_filter = getReqVal('durability_filter', 0); $rows = $this->getNftListByAccountAndType($account, $type, $order_method, $order_asc, $job_filter_array, $search_filter_array, $lv_filter, $quality_filter, $durability_filter); $total = count($rows); $page_end = $start + $page_size; if ($page_end > $total) { $page_end = $total; $start = $total - 1; $start = intval($start / $page_size) * $page_size; if ($start < 0) $start = 0; } $nfts = array(); for ($x = $start; $x < $page_end; $x++) { $row = $rows[$x]; // $this->attach_market_selling($row); array_push($nfts, $row); } $this->_rspData(array( "total" => $total, "start" => $start, "page_size" => $page_size, 'nfts' => $nfts, )); } public function sell() { $self = myself(); if (!$self) { $this->_rspErr(500, 'internal error, no self'); return; } $address = $this->_getAddress(); if (!$address) { $this->_rspErr(1, 'address not found'); return; } $account = $address; $token = getReqVal('token', ''); $nft_token = getReqVal('nft_token', ''); $item_id = getReqVal('item_id', ''); if (empty($item_id)) { $this->_rspErr(1, 'item_id not found'); return; } $s_price = getReqVal('s_price', ''); if (empty($s_price)) { $this->_rspErr(1, 's_price not found'); return; } $amount = getReqVal('amount', 1); if (empty($amount)) { $this->_rspErr(1, 'amount not found'); return; } $payment_token_address = getReqVal('payment_token_address', ''); $nonce = getReqVal('nonce', ''); $signature = getReqVal('signature', ''); $net_id = getReqVal('net_id', ''); $conn = $self->_getMysql(''); $nftDb = null; $c_name = null; $c_job = null; $c_lv = null; $c_quality = null; $c_durability = null; $c_type = null; $c_id = null; if ($nft_token) { $nftDb = Nft::findNftByOwner($account, $nft_token); $nftDetail = Nft::toDto($nftDb); $detail = $this->getNftGameData($nftDb); $c_name = $nftDetail['info']['name']; $c_job = isset($nftDetail['info']['job']) ? $nftDetail['info']['job'] : (isset($detail['chip_type']) ? $detail['chip_type'] : (isset($detail['type']) ? $detail['type'] : 0)); $c_lv = @$detail['gun_lv'] | @$detail['hero_lv'] | @$detail['chip_grade']; $c_quality = isset($nftDetail['info']['quality']) ? $nftDetail['info']['quality'] : 0; $c_durability = isset($nftDetail['info']['durability']) ? $nftDetail['info']['durability'] : (isset($detail['hero_tili']) ? $detail['hero_tili'] : 0); $c_type = isset($detail['type']) ? $detail['type'] : 0; $c_id = $nftDetail['item_id']; } else { if (!$this->decItems($account, $item_id, $amount)) { $this->_rspErr(1, 'item not enough, item_id:' . $item_id); return; } $itemMeta = mt\Item::get($item_id); $c_name = $itemMeta['name']; $c_job = 0; $c_lv = 0; $c_quality = $itemMeta['quality']; $c_durability = 0; $c_type = 0; $c_id = $item_id; } $r = SqlHelper::insert( $conn, 't_market_store', array( 'token_id' => $nft_token, 'item_id' => $item_id, 'owner_address' => $account, 'token_type' => 0, 'amount' => $amount, 'createtime' => $self->_getNowTime(), 'modifytime' => $self->_getNowTime(), 's_price' => $s_price, 'c_name' => $c_name, 'c_job' => $c_job, 'c_lv' => $c_lv, 'c_quality' => $c_quality, 'c_durability' => $c_durability, 'c_type' => $c_type, 'c_id' => $c_id, ) ); $this->_rspOk(); } public function sellCancel() { $account = strtolower(getReqVal('account', '')); $idx = getReqVal('idx', ''); $address = $this->_getAddress(); if ($address != $account) { $this->_rspErr(1, 'not your goods, idx:' . $idx); return; } $goods = $this->getGoodsByIdx($idx); if (!$goods) { $this->_rspErr(1, 'goods not found, idx:' . $idx); return; } if ($goods['owner_address'] != $account) { $this->_rspErr(1, 'not your goods, idx:' . $idx); return; } if (!$this->addItems($address, $goods['item_id'], $goods['amount'])) { $this->_rspErr(1, "cancel failed, add item failed, idx:" . $idx); return; } $conn = $this->_getMysql(''); $r = SqlHelper::update( $conn, 't_market_store', array( 'idx' => $idx, ), array( 'status' => 1, 'modifytime' => $this->_getNowTime(), ) ); $this->_rspOk(); } public function sellUpdatePrice() { $account = strtolower(getReqVal('account', '')); $idx = getReqVal('idx', ''); $s_price = getReqVal('s_price', ''); $address = $this->_getAddress(); if ($address != $account) { $this->_rspErr(1, 'not your goods, idx:' . $idx); return; } $goods = $this->getGoodsByIdx($idx); if (!$goods) { $this->_rspErr(1, 'goods not found, idx:' . $idx); return; } if ($goods['owner_address'] != $account) { $this->_rspErr(1, 'not your goods, idx:' . $idx); return; } $conn = $this->_getMysql(''); $r = SqlHelper::update( $conn, 't_market_store', array( 'idx' => $idx, ), array( 's_price' => $s_price, 'modifytime' => $this->_getNowTime(), ) ); $this->_rspOk(); } public function buy() { $account = strtolower(getReqVal('account', '')); $idx = getReqVal('idx', ''); $goods = $this->getGoodsByIdx($idx); if (!$goods) { $this->_rspErr(1, 'goods not found, idx:' . $idx); return; } $response = services\BlockChainService::gameItemMarketBuy( Transaction::BUY_GOODS_FROM_MARKET_ACTION_TYPE, $goods['owner_address'], $goods['s_price'], $goods['item_id'], $goods['amount'] ); if (!$this->markOrderBuyStatus($idx)) { $this->_rspErr(1, 'buy failed, update order status failed, idx:' . $idx); return; } $item_id = $goods['item_id']; $item_count = $goods['amount']; BcOrder::upsert($response['trans_id'], array( 'item_id' => $item_id, 'item_num' => $item_count, 'order_type' => 1, 'price' => $goods['s_price'], 'ext_data' => json_encode(array( 'mode' => SHOP_BUY_MODE_NORMAL, )), )); $this->_rspData(array( 'block_chain' => $response, )); } private function sellMyNft() { $account = strtolower(getReqVal('account', '')); $token = getReqVal('token', ''); $nft_token = getReqVal('nft_token', ''); $s_price = getReqVal('s_price', ''); $amount = getReqVal('amount', 1); $payment_token_address = getReqVal('payment_token_address', ''); $nonce = getReqVal('nonce', ''); $signature = getReqVal('signature', ''); $net_id = getReqVal('net_id', ''); $conn = myself()->_getMysql(''); $nftDb = Nft::findNftByOwner($account, $nft_token); $nftDetail = Nft::toDto($nftDb); $detail = $this->getNftGameData($nftDb); $r = SqlHelper::insert( $conn, 't_market_store', array( 'token_id' => $nft_token, 'owner_address' => $nftDetail['owner_address'], 'token_type' => $nftDetail['type'], 'amount' => $amount, 'createtime' => myself()->_getNowTime(), 'modifytime' => myself()->_getNowTime(), 's_price' => $s_price, 'c_name' => $nftDetail['info']['name'], 'c_job' => isset($nftDetail['info']['job']) ? $nftDetail['info']['job'] : (isset($detail['chip_type']) ? $detail['chip_type'] : (isset($detail['type']) ? $detail['type'] : 0)), 'c_lv' => @$detail['gun_lv'] | @$detail['hero_lv'] | @$detail['chip_grade'], 'c_quality' => isset($nftDetail['info']['quality']) ? $nftDetail['info']['quality'] : 0, 'c_durability' => isset($nftDetail['info']['durability']) ? $nftDetail['info']['durability'] : (isset($detail['hero_tili']) ? $detail['hero_tili'] : 0), 'c_type' => isset($detail['type']) ? $detail['type'] : 0, 'c_id' => $nftDetail['item_id'], ) ); $this->_rspOk(); } public function buyNft() { $account = strtolower(getReqVal('account', '')); $token = getReqVal('token', ''); $nft_token = getReqVal('nft_token', ''); $payment_token_address = getReqVal('payment_token_address', ''); $nonce = getReqVal('nonce', ''); $signature = getReqVal('signature', ''); $net_id = getReqVal('net_id', ''); $conn = myself()->_getMysql(''); $conn->execScript('DELETE FROM t_market_store WHERE ' . 'token_id=\'' . $nft_token . '\''); $this->_rspOk(); } public function getSupportedCurrencyTypes() { $types = array(); if (SERVER_ENV == _ONLINE) { array_push($types, array( 'name' => 'USDT', 'address' => '0xc22Ffa318051d8aF4E5f2E2732d7049486fcE093', )); } else { array_push($types, array( 'name' => 'USDT', 'address' => '0xc22Ffa318051d8aF4E5f2E2732d7049486fcE093', )); } $this->_rspData(array( 'list' => $types, )); } public function getTransactionRecord() { $account = strtolower(getReqVal('account', '')); $type = getReqVal('type', 0); $start = getReqVal('start', 0); $page_size = getReqVal('page_size', 10); $page_size = max(1, min(100, $page_size)); $conn = myself()->_getMysql(''); $type_filter_fn = function ($f) { if ($f == 0) { return ''; } else { return 'AND type=' . $f; } }; $counts = $conn->execQuery( 'SELECT count(*) as count FROM t_market_transaction_record ' . 'WHERE (seller=:account OR buyer=:account) ' . $type_filter_fn($type) . ' ORDER BY createtime DESC', array( ':account' => $account, ) ); $total = $counts[0]['count']; $page_end = $start + $page_size; if ($page_end > $total) { $page_end = $total; $start = $total - 1; $start = intval($start / $page_size) * $page_size; if ($start < 0) $start = 0; } $rows = $conn->execQuery( 'SELECT * FROM t_market_transaction_record ' . 'WHERE (seller=:account OR buyer=:account) ' . $type_filter_fn($type) . ' ORDER BY createtime DESC ' . 'LIMIT ' . $start . ',' . $page_size, array( ':account' => $account, ) ); $this->_rspData(array( "total" => $total, "start" => $start, "page_size" => $page_size, 'nfts' => $rows, )); } private function addTransactionRecord($record) { $conn = myself()->_getMarketMysql(''); $r = SqlHelper::insert( $conn, 't_market_transaction_record', $record ); if (!$r) { $this->_rspErr(2, 'unknown error, orderId=' . $record['orderid']); } } public function eventSellOrder() { $tokenId = getReqVal('tokenId', ''); $owner = strtolower(getReqVal('owner', '')); $nftToken = getReqVal('nftToken', ''); $amount = getReqVal('amount', 0); $orderId = getReqVal('orderId', ''); $currency = getReqVal('currency', ''); $price = getReqVal('price', ''); error_log( "eventSellOrder:" . json_encode( array( 'tokenId' => $tokenId, 'owner' => $owner, 'nftToken' => $nftToken, 'amount' => $amount, 'orderId' => $orderId, 'currency' => $currency, 'price' => $price, ), JSON_PRETTY_PRINT ) ); $conn = myself()->_getMysql(''); // 1. check order status $chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId)); if (!empty($chk)) { $this->_rspErr(1, 'repeat sell order, orderId=' . $orderId); return; } // 2. insert sell order to t_market_store $nftDb = Nft::findNftByOwner($owner, $tokenId); if (empty($nftDb)) { $nftDb = Nft::getNft($tokenId); } $nftDetail = Nft::toDto($nftDb); $detail = $this->getNftGameData($nftDb); $r = SqlHelper::insert( $conn, 't_market_store', array( 'token_id' => $tokenId, 'o_link' => $orderId, 'nft_token' => $nftToken, 'status' => 0, 'owner_address' => $owner, 'token_type' => $nftDetail['type'], 'amount' => $amount, 'createtime' => myself()->_getNowTime(), 'modifytime' => myself()->_getNowTime(), 's_currency' => $currency, 's_price' => $price, 'c_name' => $nftDetail['info']['name'], 'c_job' => isset($nftDetail['info']['job']) ? $nftDetail['info']['job'] : (isset($detail['chip_type']) ? $detail['chip_type'] : (isset($detail['type']) ? $detail['type'] : 0)), 'c_lv' => @$detail['gun_lv'] | @$detail['hero_lv'] | @$detail['chip_grade'], 'c_quality' => isset($nftDetail['info']['quality']) ? $nftDetail['info']['quality'] : 0, 'c_durability' => isset($nftDetail['info']['durability']) ? $nftDetail['info']['durability'] : (isset($detail['hero_tili']) ? $detail['hero_tili'] : 0), 'c_type' => isset($detail['type']) ? $detail['type'] : 0, 'c_id' => $nftDetail['item_id'], ) ); if (!$r) { $this->_rspErr(2, 'unknown error, orderId=' . $orderId); } $this->_rspOk(); } public function eventBuyOrder() { $tokenId = getReqVal('tokenId', ''); $orderId = getReqVal('orderId', ''); $nftToken = getReqVal('nftToken', ''); $amount = getReqVal('amount', 0); $seller = strtolower(getReqVal('seller', '')); $buyer = strtolower(getReqVal('buyer', '')); $erc20 = getReqVal('erc20', ''); $price = getReqVal('price', ''); error_log( "eventBuyOrder:" . json_encode( array( 'tokenId' => $tokenId, 'orderId' => $orderId, 'nftToken' => $nftToken, 'amount' => $amount, 'seller' => $seller, 'buyer' => $buyer, 'erc20' => $erc20, 'price' => $price, ), JSON_PRETTY_PRINT ) ); $conn = myself()->_getMysql(''); // 1. check order status $chk = SqlHelper::selectOne($conn, 't_market_store', array('status', 'idx', 'c_name', 'token_type'), array('o_link' => $orderId)); if (empty($chk)) { $this->_rspErr(1, 'not found order, orderId=' . $orderId); return; } if ($chk['status'] == '0') { $r = SqlHelper::update( $conn, 't_market_store', array( 'o_link' => $orderId, ), array( 'status' => 2, ) ); if ($r) { // 增加交易记录 $record = array( 'createtime' => myself()->_getNowTime(), 'orderid' => $chk['idx'], 'o_link' => $orderId, 'seller' => $seller, 'buyer' => $buyer, 'tokenid' => $tokenId, 'amount' => $amount, 'name' => $chk['c_name'], 'type' => $chk['token_type'], ); $this->addTransactionRecord($record); $this->_rspOk(); return; } } $this->_rspErr(1, 'order status error, order=' . $orderId); } public function eventCancelOrder() { $orderId = getReqVal('orderId', ''); $nftToken = getReqVal('nftToken', ''); $tokenId = getReqVal('tokenId', ''); error_log( "eventCancelOrder:" . json_encode( array( 'orderId' => $orderId, 'nftToken' => $nftToken, 'tokenId' => $tokenId, ), JSON_PRETTY_PRINT ) ); $conn = myself()->_getMysql(''); // 1. check order status $chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId)); if (empty($chk)) { $this->_rspErr(1, 'not found order, orderId=' . $orderId); return; } if ($chk['status'] == '0') { $r = SqlHelper::update( $conn, 't_market_store', array( 'o_link' => $orderId, ), array( 'status' => 1, ) ); if ($r) { $this->_rspOk(); return; } } $this->_rspErr(1, 'order status error, order=' . $orderId); } public function eventPriceUpdateOrder() { $orderId = getReqVal('orderId', '');; $nftToken = getReqVal('nftToken', ''); $tokenId = getReqVal('tokenId', ''); $priceOld = getReqVal('priceOld', ''); $price = getReqVal('price', ''); error_log( "eventPriceUpdateOrder:" . json_encode( array( 'orderId' => $orderId, 'nftToken' => $nftToken, 'tokenId' => $tokenId, 'priceOld' => $priceOld, 'price' => $price, ), JSON_PRETTY_PRINT ) ); $conn = myself()->_getMysql(''); // 1. check order status $chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId)); if (empty($chk)) { $this->_rspErr(1, 'not found order, orderId=' . $orderId); return; } if ($chk['status'] == '0') { $r = SqlHelper::update( $conn, 't_market_store', array( 'o_link' => $orderId, ), array( 's_price' => $price, ) ); if ($r) { $this->_rspOk(); return; } } $this->_rspErr(1, 'price update failed, orderId=' . $orderId); } private function getNftGameData($nftRowInfo) { $t = $nftRowInfo['token_type']; $token_id = $nftRowInfo['token_id']; switch ($t) { case Nft::HERO_TYPE: { return $this->appendChipsInfo(Hero::toDtoInfo(Hero::findByTokenId2($token_id))); } break; case Nft::EQUIP_TYPE: { return $this->appendChipsInfo(Gun::toDtoInfo(Gun::findByTokenId2($token_id))); } break; case Nft::CHIP_TYPE: { return Chip::toDto(Chip::getChipByTokenId($token_id)); } break; case Nft::FRAGMENT_TYPE: { return Fragment::ToDto($nftRowInfo); } break; default: { } break; } return array('unknown' => 'unknown game data type, cannot find data'); } private function appendChipsInfo($detail) { $detail['chips_info'] = array(); if (!empty($detail['chip_ids'])) { $chips = explode('|', $detail['chip_ids']); foreach ($chips as $chip) { $chip_info = ""; if (!empty($chip)) { $chip_info = Chip::toDto(Chip::getChipByTokenId($chip)); } array_push($detail['chips_info'], $chip_info); } } return $detail; } private function attach_market_selling(&$row) { $conn = myself()->_getMysql(''); $rows = $conn->execQuery( 'SELECT * FROM t_market_store ' . 'WHERE token_id=:token_id AND owner_address=:owner_address AND status=:status', array( ':token_id' => $row['token_id'], ':owner_address' => $row['owner_address'], ':status' => 0, ) ); $count = 0; $link_array = array(); foreach ($rows as $r) { $count += $r['amount']; array_push($link_array, $r['o_link']); } $row['o_link'] = implode('|', $link_array); $row['selling'] = $count; } private function listMySelledNfts($account, $type) { // error_log('listMySelledNfts ' . $account . ' ' . $type); $conn = myself()->_getMysql(''); $rows = $conn->execQuery( 'SELECT * FROM t_market_store ' . 'WHERE owner_address=:account AND token_type=:token_type AND status=0 ', array( ':account' => $account, ':token_type' => $type, ) ); return $rows; } private function addItems($address, $item_id, $amount) { $self = myself(); if (!$self) { return false; } $r = $this->addItem($address, $item_id, $amount); if (!$r) { return false; } return true; } private function decItems($address, $item_id, $amount) { $self = myself(); if (!$self) { return false; } $userInfo = $this->getUserInfo($address, array('gold')); $count = $this->getItemCount($item_id, $userInfo); if ($count < $amount) { return false; } $r = $this->decItem($address, $item_id, $amount); if (!$r) { return false; } return true; } private function addItem($address, $item_id, $amount) { $self = myself(); if (!$self) { return false; } switch ($item_id) { case V_ITEM_GOLD: { $r = $this->addGold($address, $amount); if (!$r) { return false; } } break; } return true; } private function decItem($address, $item_id, $amount) { $self = myself(); if (!$self) { return false; } switch ($item_id) { case V_ITEM_GOLD: { $r = $this->decGold($address, $amount); if (!$r) { return false; } } break; } return true; } private function addGold($address, $amount) { $self = myself(); if (!$self) { return false; } $r = $this->updateUserInfo($address, array( 'gold' => function () use ($amount) { return "gold + ${amount}"; } )); if (!$r) { return false; } return true; } private function decGold($address, $amount) { $self = myself(); if (!$self) { return false; } $userInfo = $this->getUserInfo($address, array('gold')); $count = $this->getItemCount(V_ITEM_GOLD, $userInfo); if ($count < $amount) { return false; } $r = $this->updateUserInfo($address, array( 'gold' => function () use ($amount) { return "GREATEST(0, gold - ${amount})"; }, 'consume_gold' => function () use ($amount) { return "consume_gold + ${amount}"; } )); if (!$r) { return false; } return true; } private function updateUserInfo($address, $fieldKv) { $self = myself(); if (!$self) { return false; } $r = SqlHelper::update( $self->_getMysql(''), 't_user', array( 'address' => $address, ), $fieldKv ); if (!$r) { return false; } return true; } private function getCostItem($address, $item_id) { $self = myself(); if (!$self) { return null; } $userInfo = $this->getUserInfo($address, array('gold')); $count = $this->getItemCount($item_id, $userInfo); return array( 'item_id' => $item_id, 'item_amount' => $count ); } private function getItemCount($item_id, $userInfo) { switch ($item_id) { case V_ITEM_GOLD: { return $userInfo['gold']; } } return "0"; } private function getUserInfo($address, $fields) { $self = myself(); if (!$self) { return null; } // $account_id = $this->getAccountId($address); // if (!$account_id) { // return null; // } $conn = $self->_getMysql($address); $row = SqlHelper::selectOne( $conn, 't_user', $fields, array( 'address' => $address ) ); if (empty($row)) { return null; } return $row; } private function getAccountId($address) { $self = myself(); if (!$self) { return null; } $row = SqlHelper::selectOne( $self->_getMysql($address), 't_user', array('account_id'), array( 'address' => $address ) ); return $row['account_id']; } private function normalizeWeb3Price($price) { $bn1 = phpcommon\bnInit($price * pow(10, 8)); $bn2 = phpcommon\bnInit('1000000000000000000'); $ret_price = phpcommon\bnDiv(phpcommon\bnMul($bn1, $bn2), pow(10, 8)); // error_log('normalizeWeb3Price: ' . $ret_price . ' ' . $price * pow(10, 8)); return phpcommon\bnToStr($ret_price); } private function getGoodsByIdx($idx) { $self = myself(); if (!$self) { return null; } $row = SqlHelper::selectOne( $self->_getMysql(''), 't_market_store', array('item_id', 'amount', 's_price', 'owner_address'), array( 'idx' => $idx, 'status' => 0, ) ); if (!$row) { return null; } if (!$row['item_id']) { return null; } return $row; } private function markOrderBuyStatus($idx) { $self = myself(); if (!$self) { return false; } $r = SqlHelper::update( $self->_getMysql(''), 't_market_store', array( 'idx' => $idx, ), array( 'status' => 3, 'buytime' => $self->_getNowTime(), ) ); if (!$r) { return false; } return true; } }