diff --git a/doc/Market.py b/doc/Market.py index 8f1853b1..75256719 100644 --- a/doc/Market.py +++ b/doc/Market.py @@ -105,6 +105,42 @@ class Market(object): ['order_id', '', '订单号(errcode = 0的时候,根据订单号客户端定时调用queryOrder接口)查询状态'], ] }, + { + 'name': 'openLuckyBox', + 'desc': '开宝箱', + 'group': 'Market', + 'url': 'webapp/index.php?c=Market&a=openLuckyBox', + 'params': [ + ['account', 0, '钱包账号'], + ['token', '', 'token'], + ['token_id', '', '宝箱token_id'], + ['net_id', '', '网络id'], + ], + 'response': [ + _common.RspHead(), + ['!tokenIds', [''], '开出的物品tokenId列表'], + ['nonce', '', 'nonce'], + ['signature', '', 'signature'], + ] + }, + { + 'name': 'queryLuckyBox', + 'desc': '查询开宝箱信息', + 'group': 'Market', + 'url': 'webapp/index.php?c=Market&a=queryLuckyBox', + 'params': [ + ['account', 0, '钱包账号'], + ['token', '', 'token'], + ['token_id', '', '宝箱token_id'], + ['txhash', '', 'txhash'], + ['net_id', '', '网络id'], + ], + 'response': [ + _common.RspHead(), + ['state', '', '0:开启中 1:开启成功'], + ['!nfts', [_common.NftDetail()], '获得的nft列表'], + ] + }, { 'name': 'queryOrder', 'desc': '查询订单状态', diff --git a/sql/marketdb.sql b/sql/marketdb.sql index 3db3d21a..b0f2a607 100644 --- a/sql/marketdb.sql +++ b/sql/marketdb.sql @@ -167,6 +167,7 @@ CREATE TABLE `t_nft` ( `item_id` int(11) NOT NULL DEFAULT '0' COMMENT '道具id', `deleted` int(11) NOT NULL DEFAULT '0' COMMENT 'deleted', `opened` int(11) NOT NULL DEFAULT '0' COMMENT 'opened', + `confirm_block_number` bigint NOT NULL DEFAULT '0' COMMENT 'confirm_block_number', `rand_attr` mediumblob COMMENT '随机属性', `tags` varchar(60) NOT NULL DEFAULT '' COMMENT 'tags', `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', @@ -178,6 +179,97 @@ CREATE TABLE `t_nft` ( ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `t_lucky_box` +-- + +DROP TABLE IF EXISTS `t_lucky_box`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t_lucky_box` ( + `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `box_token_id` varchar(60) NOT NULL DEFAULT '' COMMENT 'box_token_id', + `account` varchar(60) NOT NULL DEFAULT '' COMMENT 'account', + `token_id1` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id1', + `token_id2` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id2', + `token_id3` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id3', + `token_type1` int(11) NOT NULL DEFAULT '0' COMMENT 'token_type1', + `token_type2` int(11) NOT NULL DEFAULT '0' COMMENT 'token_type2', + `token_type3` int(11) NOT NULL DEFAULT '0' COMMENT 'token_type3', + `nonce` varchar(60) NOT NULL DEFAULT '' COMMENT 'nonce', + `signature` varchar(255) NOT NULL DEFAULT '' COMMENT '签名', + `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', + PRIMARY KEY (`idx`), + UNIQUE KEY `box_token_id` (`box_token_id`), + UNIQUE KEY `token_id1` (`token_id1`), + UNIQUE KEY `token_id2` (`token_id2`), + UNIQUE KEY `token_id3` (`token_id3`) +) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `t_boxopened_event` +-- + +DROP TABLE IF EXISTS `t_boxopened_event`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t_boxopened_event` ( + `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `box_token_id` varchar(60) NOT NULL DEFAULT '' COMMENT 'box_token_id', + `txhash` varchar(255) NOT NULL DEFAULT '' COMMENT 'txhash', + `block_number` bigint NOT NULL DEFAULT '0' COMMENT 'block_number', + `log_index` bigint NOT NULL DEFAULT '0' COMMENT 'log_index', + `_to` varchar(60) NOT NULL DEFAULT '' COMMENT '_to', + `token_id1` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id1', + `token_id2` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id2', + `token_id3` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id3', + `token_type1` int(11) NOT NULL DEFAULT '0' COMMENT 'token_type1', + `token_type2` int(11) NOT NULL DEFAULT '0' COMMENT 'token_type2', + `token_type3` int(11) NOT NULL DEFAULT '0' COMMENT 'token_type3', + `raw_data` mediumblob COMMENT 'raw_data', + `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', + PRIMARY KEY (`idx`), + KEY `box_token_id` (`box_token_id`), + KEY `token_id1` (`token_id1`), + KEY `token_id2` (`token_id2`), + KEY `token_id3` (`token_id3`), + KEY `txhash` (`txhash`), + KEY `block_number` (`block_number`) +) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `t_nft_transfer` +-- + +DROP TABLE IF EXISTS `t_nft_transfer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t_nft_transfer` ( + `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `token_id` varchar(60) NOT NULL DEFAULT '' COMMENT 'token_id', + `txhash` varchar(255) NOT NULL DEFAULT '' COMMENT 'txhash', + `block_number` bigint NOT NULL DEFAULT '0' COMMENT 'block_number', + `log_index` bigint NOT NULL DEFAULT '0' COMMENT 'log_index', + `_from` varchar(60) NOT NULL DEFAULT '' COMMENT '_from', + `_to` varchar(60) NOT NULL DEFAULT '' COMMENT '_to', + `raw_data` mediumblob COMMENT 'raw_data', + `owner_confirmed` int(11) NOT NULL DEFAULT '0' COMMENT 'owner_confirmed', + `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', + PRIMARY KEY (`idx`), + UNIQUE KEY `txhash_log_index` (`txhash`, `log_index`), + KEY `token_id` (`token_id`), + KEY `_from` (`_from`), + KEY `_to` (`_to`), + KEY `txhash` (`txhash`), + KEY `block_number` (`block_number`) +) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `t_buy_record` -- diff --git a/third_party/phpcommon b/third_party/phpcommon index 3b7fcfd9..066f9dc7 160000 --- a/third_party/phpcommon +++ b/third_party/phpcommon @@ -1 +1 @@ -Subproject commit 3b7fcfd92d5ca5fa4e25ebf3895940df482ba63d +Subproject commit 066f9dc70f7ab15c1277fa3e84d3197fb87705da diff --git a/webapp/controller/MarketController.class.php b/webapp/controller/MarketController.class.php index c5bf232e..4b47a0a0 100644 --- a/webapp/controller/MarketController.class.php +++ b/webapp/controller/MarketController.class.php @@ -1,4 +1,4 @@ - _rspErr(1, 'invalid token'); + return; + } + LuckyBoxService::open($account, $tokenId, $netId); + } + + public function queryLuckyBox() + { + $this->queryLuckyBoxResult(); + } + + public function queryLuckyBoxResult() + { + $token = getReqVal('token', ''); + $account = getReqVal('account', ''); + $tokenId = getReqVal('token_id', ''); + $netId = getReqVal('net_id', ''); + $account = strtolower(getReqVal('account', '')); + if (!MarketService::isValidToken($account, $token)) { + myself()->_rspErr(1, 'invalid token'); + return; + } + LuckyBoxService::queryResult($account, $tokenId, $netId); + } + } diff --git a/webapp/models/BoxOpenedEvent.php b/webapp/models/BoxOpenedEvent.php new file mode 100644 index 00000000..54632161 --- /dev/null +++ b/webapp/models/BoxOpenedEvent.php @@ -0,0 +1,22 @@ +_getMarketMysql(), + 't_boxopened_event', + array( + 'box_token_id' => $boxId, + ) + ); + return $row; + } + +} diff --git a/webapp/models/LuckyBox.php b/webapp/models/LuckyBox.php new file mode 100644 index 00000000..ba03a2af --- /dev/null +++ b/webapp/models/LuckyBox.php @@ -0,0 +1,38 @@ +_getMarketMysql(), + 't_lucky_box', + array( + 'box_token_id' => $boxTokenId, + ) + ); + return $row; + } + + + public static function add($boxTokenId, $account, $tokenIds) + { + SqlHelper::insert( + myself()->_getMarketMysql(), + 't_lucky_box', + array( + 'box_token_id' => $boxTokenId, + 'account' => $account, + 'token_id1' => $tokenIds[0], + 'token_id2' => $tokenIds[1], + 'token_id3' => $tokenIds[2], + ) + ); + } + +} diff --git a/webapp/models/Nft.php b/webapp/models/Nft.php index 67b1b489..80630614 100644 --- a/webapp/models/Nft.php +++ b/webapp/models/Nft.php @@ -40,6 +40,11 @@ class Nft extends BaseModel { } } break; + case mt\Item::BLIND_BOX_TYPE: + { + return self::BLIND_BOX_TYPE; + } + break; } return self::NONE_TYPE; } @@ -51,10 +56,13 @@ class Nft extends BaseModel { myself()->_getMarketMysql(), 't_nft', array( - 'owner_address' => $account + 'owner_address' => $account, + 'deleted' => 0, ), function ($row) use(&$nftList) { - array_push($nftList, $row); + if (self::isVisableNft($row)) { + array_push($nftList, $row); + } } ); return $nftList; @@ -100,6 +108,9 @@ class Nft extends BaseModel { if (in_array(self::GENESIS_TAG, $tags)) { $image = 'https://www.cebg.games/res/avatars/' . $itemMeta['id'] . '_1' . '.png'; } + if ($nftDb['token_type'] == self::CHIP_TYPE) { + $image = 'https://www.cebg.games/res/avatars/' . $itemMeta['id'] . '_a' . '.png'; + } $nft = array( 'token_id' => $nftDb['token_id'], 'owner_address' => $nftDb['owner_address'], @@ -200,10 +211,20 @@ class Nft extends BaseModel { } } - private function parseTags($tagsStr) + private static function parseTags($tagsStr) { $tags = explode('|', $tagsStr); return $tags; } + private static function isVisableNft($nftDb) + { + return in_array($nftDb['token_type'], + array( + self::HERO_TYPE, + self::EQUIP_TYPE, + self::CHIP_TYPE + )); + } + } diff --git a/webapp/services/LuckyBoxService.php b/webapp/services/LuckyBoxService.php new file mode 100644 index 00000000..c83fa8d4 --- /dev/null +++ b/webapp/services/LuckyBoxService.php @@ -0,0 +1,126 @@ +_rspErr(2, 'box not found'); + return; + } + if ($nftDb['token_type'] != Nft::BLIND_BOX_TYPE) { + myself()->_rspErr(2, 'paramater error'); + return; + } + $luckyDb = LuckyBox::find($tokenId); + if (!$luckyDb) { + $tokenIds = array(); + for ($i = 0; $i < 3; ++$i) { + $newTokenId = BuyRecord::genOrderId(2006, + phpcommon\BC_FUNC_OPEN_BOX, + time(), + $account); + if (!phpcommon\isValidOrderId($newTokenId)) { + myself()->_rspErr(2, 'server internal error'); + return; + } + array_push($tokenIds, $newTokenId); + } + LuckyBox::add($tokenId, $account, $tokenIds); + } + $luckyDb = LuckyBox::find($tokenId); + if (!$luckyDb) { + myself()->_rspErr(2, 'server internal error3'); + return; + } + { + $params = array( + 'c' => 'BcService', + 'a' => 'openBoxSignature', + 'account' => $account, + 'box_token_id' => $tokenId, + 'token_id1' => $luckyDb['token_id1'], + 'token_id2' => $luckyDb['token_id2'], + 'token_id3' => $luckyDb['token_id3'], + ); + $url = self::getWeb3ServiceUrl(); + $response = ''; + if (!phpcommon\HttpClient::get + ($url, + $params, + $response)) { + phpcommon\sendError(500, 'server internal error'); + die(); + return; + } + error_log(json_encode(array( + '_REQUEST' => $_REQUEST, + 'params' => $params, + 'response' => $response + ))); + $json = json_decode($response, true); + myself()->_rspData(array( + 'nonce' => $json['nonce'], + 'signature' => $json['signature'], + 'tokenIds' => array( + $luckyDb['token_id1'], + $luckyDb['token_id2'], + $luckyDb['token_id3'], + ) + )); + } + } + + public static function queryResult($account, $tokenId, $netId) + { + $eventDb = BoxOpenedEvent::find($tokenId); + if (!$eventDb) { + myself()->_rspData(array( + 'state' => 0, + 'nfts'=> array() + )); + return; + } + $nfts = array(); + for ($i = 1; $i <= 3; ++$i) { + if ($eventDb['token_id' . $i]) { + $nftDb = Nft::getNft($eventDb['token_id' . $i]); + if (!$nftDb) { + myself()->_rspData(array( + 'state' => 0, + 'nfts'=> array() + )); + return; + } + array_push($nfts, Nft::toDto($nftDb)); + } + } + myself()->_rspData(array( + 'state' => 1, + 'nfts'=> $nfts + )); + } + + private static function getWeb3ServiceUrl() + { + $web3ServiceCluster = require_once('../config/web3service.cluster.php'); + return $web3ServiceCluster[rand() % count($web3ServiceCluster)]; + } + +}