From 51a1f207f2e6fe1e9a9d25e68d80db7b9cb58e93 Mon Sep 17 00:00:00 2001 From: songliang Date: Tue, 20 Jun 2023 12:49:43 +0800 Subject: [PATCH 1/4] ... --- webapp/bootstrap/constant.php | 3 + webapp/controller/ShopController.class.php | 91 +++++++++++++++---- webapp/models/Transaction.php | 1 + webapp/services/BlockChainService.php | 2 + .../callback/BuyShopGoodsCbService.php | 45 +++++++++ 5 files changed, 125 insertions(+), 17 deletions(-) diff --git a/webapp/bootstrap/constant.php b/webapp/bootstrap/constant.php index e38173bc..3d74705b 100644 --- a/webapp/bootstrap/constant.php +++ b/webapp/bootstrap/constant.php @@ -59,6 +59,9 @@ define('TN_WEEKLY_RECHARGE_UPGRADE_TIMES', 10004); define('TN_WEEKLY_SHARE_GAMES', 10005); define('TN_WEEKLY_END', 10005); +define('SHOP_BUY_MODE_NORMAL', 0); +define('SHOP_BUY_MODE_DAILY_SELECTION', 1); + const kHAT_Begin = 0; const kHAT_Hp = 1; const kHAT_HPRecover = 2; diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index 912318f3..3889e38e 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -17,10 +17,16 @@ require_once('models/Gun.php'); require_once('models/GunSkin.php'); require_once('models/ShopBuyRecord.php'); require_once('models/Chip.php'); +require_once('models/BcOrder.php'); +require_once('models/Transaction.php'); require_once('services/AwardService.php'); require_once('services/PropertyChgService.php'); +require_once('services/BlockChainService.php'); +require_once('phpcommon/bignumber.php'); + +use phpcommon; use phpcommon\HttpClient; use phpcommon\SqlHelper; use models\User; @@ -34,6 +40,8 @@ use models\Chip; use mt\Shop; use mt\PayMethod; use mt\Dailyselection; +use models\Transaction; +use models\BcOrder; class ShopController extends BaseAuthedController { @@ -813,33 +821,73 @@ class ShopController extends BaseAuthedController $grid = getReqVal('grid', 0); $count = getReqVal('count', 0); - $address = $this->_getAddress(); - // $chk = $this->decDailySelectionItem($idx, $grid, $count); - // if (!$chk) { - // $this->_rspErr(1, 'goods not enough'); - // return; - // } + $conn = $this->_getMysql(''); - $url = "192.168.100.39:7672/webapp/index.php"; - $params = array( - 'c' => 'GameItemMall', - 'a' => 'buy', - 'address' => $address, - 'price' => 100, + $row = SqlHelper::selectOne( + $conn, + 't_shop_dailyselection', + array( + 'idx', + 'address', + 'grid_' . $grid, + 'count_' . $grid, + ), + array('idx' => $idx) ); - if (!phpcommon\HttpClient::get($url, $params, $response)) { - $this->_rspErr(500, 'GameItemMall buy failed'); + + if (!$row) { + $this->_rspErr(2, 'idx is invalid'); return; } - $response = ''; - error_log($response); + + if ($row['address'] != $address) { + $this->_rspErr(2, 'address is invalid'); + return; + } + + if ($row['grid_' . $grid] == 0) { + $this->_rspErr(2, 'grid is invalid'); + return; + } + + if ($row['count_' . $grid] < $count) { + $this->_rspErr(2, 'count is invalid'); + return; + } + + $sel_id = $row['grid_' . $grid]; + + $goods = mt\Dailyselection::get($sel_id); + + $price = $this->normalizeWeb3Price($goods['price'] * $count); + $item_id = $goods['goods_id']; + $item_count = $goods['goods_num'] * $count; + + $response = services\BlockChainService::gameItemMallBuy( + Transaction::BUY_GOODS_ACTION_TYPE, + $price, + $item_id, + $item_count, + ); + + BcOrder::upsert( $response['trans_id'], array( + 'item_id' => $item_id, + 'item_num' => $item_count, + 'order_type' => 1, + 'ext_data' => json_encode(array( + 'mode' => SHOP_BUY_MODE_DAILY_SELECTION, + 'idx' => $idx, + 'grid' => $grid, + 'count' => $count, + )), + )); $this->_rspData( array( 'idx' => $idx, 'grid' => $grid, 'count' => $count, - 'response' => $response, + 'trans' => $response, ) ); } @@ -1258,4 +1306,13 @@ class ShopController extends BaseAuthedController $row = $conn->execQueryOne('SELECT LAST_INSERT_ID() as lastId;', array()); return $row['lastId']; } + + private function normalizeWeb3Price($price) + { + $bn1 = phpcommon\bnInit($price * pow(10, 8)); + $bn2 = phpcommon\bnInit('1000000000000000000'); + $price = phpcommon\bnDiv(phpcommon\bnMul($bn1, $bn2), pow(10, 8)); + + return $price; + } } diff --git a/webapp/models/Transaction.php b/webapp/models/Transaction.php index 357a2349..b82cbaa4 100644 --- a/webapp/models/Transaction.php +++ b/webapp/models/Transaction.php @@ -20,6 +20,7 @@ class Transaction extends BaseModel { const BUY_EXP_ACTION_TYPE = 101; const BUY_PASS_ACTION_TYPE = 102; + const BUY_GOODS_ACTION_TYPE = 103; const BUY_END_ACTION_TYPE = 200; diff --git a/webapp/services/BlockChainService.php b/webapp/services/BlockChainService.php index 77f673ab..68bcefde 100644 --- a/webapp/services/BlockChainService.php +++ b/webapp/services/BlockChainService.php @@ -5,6 +5,7 @@ namespace services; require_once('models/Transaction.php'); use models\Transaction; +use phpcommon; class BlockChainService { @@ -83,6 +84,7 @@ class BlockChainService { private static function getWeb3ServiceUrl() { + return 'http://192.168.100.39:7672/webapp/index.php'; if (SERVER_ENV == _TEST) { return 'http://127.0.0.1:7672/webapp/index.php'; } diff --git a/webapp/services/callback/BuyShopGoodsCbService.php b/webapp/services/callback/BuyShopGoodsCbService.php index def4688d..05c2de70 100644 --- a/webapp/services/callback/BuyShopGoodsCbService.php +++ b/webapp/services/callback/BuyShopGoodsCbService.php @@ -3,10 +3,55 @@ namespace services; +define('V_ORDER_TYPE_BUY_SHOP_GOODS', 1); + +use phpcommon\SqlHelper; class BuyShopGoodsCbService { public function process($order){ + switch($order['order_type']){ + case V_ORDER_TYPE_BUY_SHOP_GOODS : { + $ext_data = json_decode($order['ext_data'], true); + switch($ext_data['mode']) + { + case SHOP_BUY_MODE_NORMAL: + $this->_buyNormal($order, $ext_data); + break; + case SHOP_BUY_MODE_DAILY_SELECTION: + $this->_buyDailySelection($order, $ext_data); + break; + } + } + break; + default : { + + } + } + } + + private function _buyNormal($order, $ext_data){ + $ext_data = $order['ext_data']; + $goods_id = $ext_data['goods_id']; + $goods_num = $ext_data['goods_num']; + $goodsDb = SqlHelper::ormSelectOne( + myself()->_getMysql($order['address']), + 't_shop_goods', + array( + 'id' => $goods_id + ) + ); + $goodsDb['goods_num'] = $goods_num; + $this->_addGoods($order['address'],$goodsDb); + } + + private function _buyDailySelection($order, $ext_data){ + + $idx = $ext_data['idx']; + $grid = $ext_data['grid']; + $count = $ext_data['count']; + } + } \ No newline at end of file From 96227fa951959d62fd89345027bb72293b9cd8c0 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 20 Jun 2023 14:54:35 +0800 Subject: [PATCH 2/4] 1 --- doc/Battle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/Battle.py b/doc/Battle.py index 729c7924..476df3e7 100644 --- a/doc/Battle.py +++ b/doc/Battle.py @@ -136,6 +136,7 @@ class Battle(object): ['parachute',0,'降落伞 item id'], ['hero_skin',0,'英雄皮肤 item id'], ['skill_id',0,'备战技能 item id'], + ['battle_times',0,'战斗次数'], ['chip_page',_common.Attr(),'铭文页属性'], ['hero_dto','','英雄详情'], ['weapon_dto1','','武器1详情'], From 2841bd490b9570775201bae4a2fda1911d8cf7a1 Mon Sep 17 00:00:00 2001 From: songliang Date: Tue, 20 Jun 2023 15:15:12 +0800 Subject: [PATCH 3/4] ... --- webapp/controller/ShopController.class.php | 128 ++++++++++++++++++ .../callback/BuyShopGoodsCbService.php | 105 +++++++++----- 2 files changed, 200 insertions(+), 33 deletions(-) diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index 3889e38e..225e08fb 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -809,6 +809,134 @@ class ShopController extends BaseAuthedController ); } + public function buyGoodsNormal() + { + $id = getReqVal('id', 0); + $token_type = getReqVal('token_type', ''); + $goods_num = getReqVal('goods_num', 0); + + $row = mt\ShopGoods::get($id); + + $desired_token_type = $row['token_type']; + $check_token_type = splitStr1($desired_token_type); + $token_pos = array_search($token_type, $check_token_type, true); + if (!in_array($token_type, $check_token_type)) { + $this->_rspErr(1, "token_type parameter error, desired_token_type: {$desired_token_type}"); + return; + } + + if ($goods_num > $row['max_amount']) { + $this->_rspErr(1, "goods_num parameter error, max_amount: {$row['max_amount']}"); + return; + } + + // 这里命名混乱了, 购买个数,一捆个数命名冲突 + $goods_count = $row['goods_num']; + + $buyRecordHash = ShopBuyRecord::allToHash(); + $boughtTimes = 1; + switch ($row['limit_type']) { + case ShopController::DAILY_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $id); + $boughtTimes = $buyRecord ? $buyRecord['this_day_buy_times'] + 1 : 1; + if ($buyRecord && getXVal($buyRecord, 'this_day_buy_times', 0) >= $row['limit_num']) { + $this->_rspErr(2, 'Has reached the maximum number of purchase restrictions today'); + return; + } + if ($row['limit_num'] <= 0) { + $this->_rspErr(2, 'The maximum number of purchase restrictions has been reached'); + return; + } + } + break; + case ShopController::WEEKLY_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $id); + $boughtTimes = $buyRecord ? $buyRecord['this_week_buy_times'] + 1 : 1; + if ($buyRecord && getXVal($buyRecord, 'this_week_buy_times', 0) >= $row['limit_num']) { + $this->_rspErr(2, 'The maximum number of purchase restrictions this week has been reached'); + return; + } + if ($row['limit_num'] <= 0) { + $this->_rspErr(2, 'The maximum number of purchase restrictions has been reached'); + return; + } + } + break; + case ShopController::TOTAL_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $id); + $boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + 1 : 1; + if ($buyRecord && getXVal($buyRecord, 'total_buy_times', 0) >= $row['limit_num']) { + $this->_rspErr(2, 'The maximum number of purchase restrictions has been reached'); + return; + } + if ($row['limit_num'] <= 0) { + $this->_rspErr(2, 'he maximum number of purchase restrictions has been reached'); + return; + } + } + break; + default: { + } + break; + } + + $price_array = splitStr1($row['price']); + $discount_array = splitStr1($row['discount']); + + $need_price = $price_array[$token_pos]; + $discount = $discount_array[$token_pos]; + + $discount_begin = strtotime($row['discount_begin'] . ' UTC'); + $discount_end = strtotime($row['discount_end'] . ' UTC'); + $nowTime = $this->_getNowTime(); + + if ($nowTime >= $discount_begin && $nowTime < $discount_end) { + + $need_price = ceil($need_price * ($discount / 100.0)); + } + + $costItemId = $this->getCostItemIdByTokenType($token_type); + + switch ($token_type) { + case ShopController::TOKEN_TYPE_CEG: + case ShopController::TOKEN_TYPE_CEC: + + $price = $this->normalizeWeb3Price($goods_num * $need_price); + $item_id = $row['goods_id']; + $item_count = $goods_num; + + $response = services\BlockChainService::gameItemMallBuy( + Transaction::BUY_GOODS_ACTION_TYPE, + $price, + $item_id, + $item_count, + ); + + BcOrder::upsert( $response['trans_id'], array( + 'item_id' => $item_id, + 'item_num' => $item_count, + 'order_type' => 1, + 'ext_data' => json_encode(array( + 'mode' => SHOP_BUY_MODE_NORMAL, + )), + )); + + $this->_rspOK(); + break; + + case ShopController::TOKEN_TYPE_BCEG: + break; + + case ShopController::TOKEN_TYPE_USDT: + case ShopController::TOKEN_TYPE_USDC: + case ShopController::TOKEN_TYPE_BUSD: + case ShopController::TOKEN_TYPE_MATIC: + case ShopController::TOKEN_TYPE_BNB: + default: + $this->_rspErr(1, "token_type is unsupport, {$token_type}"); + } + } + public function buyGoodsDS() { $address = $this->_getAddress(); diff --git a/webapp/services/callback/BuyShopGoodsCbService.php b/webapp/services/callback/BuyShopGoodsCbService.php index 05c2de70..289d8b1b 100644 --- a/webapp/services/callback/BuyShopGoodsCbService.php +++ b/webapp/services/callback/BuyShopGoodsCbService.php @@ -3,55 +3,94 @@ namespace services; +require_once('mt/Dailyselection.php'); + define('V_ORDER_TYPE_BUY_SHOP_GOODS', 1); use phpcommon\SqlHelper; +use mt\Dailyselection; class BuyShopGoodsCbService { - public function process($order){ - switch($order['order_type']){ - case V_ORDER_TYPE_BUY_SHOP_GOODS : { - $ext_data = json_decode($order['ext_data'], true); - switch($ext_data['mode']) - { - case SHOP_BUY_MODE_NORMAL: - $this->_buyNormal($order, $ext_data); - break; - case SHOP_BUY_MODE_DAILY_SELECTION: - $this->_buyDailySelection($order, $ext_data); - break; + public function process($order) + { + switch ($order['order_type']) { + case V_ORDER_TYPE_BUY_SHOP_GOODS: { + $ext_data = json_decode($order['ext_data'], true); + switch ($ext_data['mode']) { + case SHOP_BUY_MODE_NORMAL: + $this->_buyNormal($order, $ext_data); + break; + case SHOP_BUY_MODE_DAILY_SELECTION: + $this->_buyDailySelection($order, $ext_data); + break; + } + } + break; + default: { } - } - break; - default : { - - } } } - private function _buyNormal($order, $ext_data){ + private function _buyNormal($order, $ext_data) + { + $self = myself(); + if (!$self) { + return; + } + + $address = $order['address']; $ext_data = $order['ext_data']; - $goods_id = $ext_data['goods_id']; - $goods_num = $ext_data['goods_num']; - $goodsDb = SqlHelper::ormSelectOne( - myself()->_getMysql($order['address']), - 't_shop_goods', - array( - 'id' => $goods_id - ) - ); - $goodsDb['goods_num'] = $goods_num; - $this->_addGoods($order['address'],$goodsDb); + $goods_id = $order['item_id']; + $goods_num = $order['item_num']; + + $this->_addGoods($address, array( + 'goods_id' => $goods_id, + 'goods_num' => $goods_num, + )); } - private function _buyDailySelection($order, $ext_data){ + private function _buyDailySelection($order, $ext_data) + { + $self = myself(); + if (!$self) { + return; + } + $order_id = $order['order_id']; + $item_id = $order['item_id']; + $item_num = $order['item_num']; + $address = $order['address']; $idx = $ext_data['idx']; $grid = $ext_data['grid']; $count = $ext_data['count']; - + $conn = $self->_getMysql($address); + $sql = "SELECT count_$grid FROM t_shop_dailyselection WHERE idx = $idx"; + $chk = $conn->execQuery($sql); + if (!$chk) { + return; + } + if ($chk[0]['count_' . $grid] < $count) { + error_log("BuyShopGoodsCbService::_buyDailySelection() count not enough, address: $address, order_id: $order_id, idx: $idx, grid: $grid, count: $count"); + return; + } + + $sql = "UPDATE t_shop_dailyselection SET count_$grid = count_$grid - $count WHERE idx = $idx"; + $chk = $conn->execScript($sql); + + if ($chk) { + $this->_addGoods($address, array( + 'goods_id' => $item_id, + 'goods_num' => $item_num, + )); + } else { + error_log("BuyShopGoodsCbService::_buyDailySelection() decDailySelectionItem failed, address: $address, order_id: $order_id, idx: $idx, grid: $grid, count: $count"); + } } - -} \ No newline at end of file + + private function _addGoods($address, $goods) + { + error_log("BuyShopGoodsCbService::_addGoods() address: $address, goods: " . json_encode($goods)); + } +} From de6f83cc122b62cc677b36640b702fb927e89259 Mon Sep 17 00:00:00 2001 From: songliang Date: Tue, 20 Jun 2023 15:56:24 +0800 Subject: [PATCH 4/4] ... --- webapp/controller/ShopController.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index 225e08fb..014ef306 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -46,6 +46,7 @@ use models\BcOrder; class ShopController extends BaseAuthedController { + const TOKEN_TYPE_GOLD = '0'; const TOKEN_TYPE_CEG = '1'; const TOKEN_TYPE_CEC = '2'; const TOKEN_TYPE_BCEG = '3';