load(); } public function info() { $goodsList = array(); $slot = 1; foreach ($this->data['grid_list'] as $grid) { $meta = mt\Dailyselection::get($grid['id']); if ($meta) { array_push($goodsList, array( 'slot' => $slot, 'count' => $grid['count'], 'goods_meta' => array( 'goods_id' => $meta['id'], 'item_id' => $meta['goods_id'], 'item_num' => $meta['goods_num'], 'price' => $meta['price'], 'discount' => $meta['discount'], 'token_type' => $meta['token_type'], ) )); } ++$slot; } $count = $this->data['refresh_count']; $costs = mt\Parameter::getByName('daily_selection_refresh_cost'); $arrCosts = explode('|', $costs['param_value']); $maxCount = count($arrCosts); $cost = $count < $maxCount ? $arrCosts[$count] : -1; $this->_rspData( array( 'refresh_count' => min($maxCount, $this->data['refresh_count']), 'refresh_max_count' => $maxCount, 'cost' => $cost, 'goods_list' => $goodsList, ) ); } public function refresh() { $costs = mt\Parameter::getByName('daily_selection_refresh_cost'); $arrCosts = explode('|', $costs['param_value']); $maxCount = count($arrCosts); $count = $this->data['refresh_count']; if ($count >= $maxCount) { myself()->_rspErr(1, 'The maximum number of refreshes has been reached'); return; } $cost = $arrCosts[$count]; $costItems = array( array( 'item_id' => V_ITEM_GOLD, 'item_num' => $cost ) ); $lackItem = null; if (!myself()->_hasEnoughItems($costItems, $lackItem)) { myself()->_rspErr(2, $this->_getLackItemErrMsg($lackItem)); return; } myself()->_decItems($costItems); $this->internalRefresh(true); $this->save(); $propertyChgService = new PropertyChgService(); $propertyChgService->addUserChg(); ++$count; $newCost = $count < $maxCount ? $arrCosts[$count] : -1; myself()->_rspData(array( 'cost' => $newCost, 'property_chg' => $propertyChgService->toDto() )); } public function buy() { $grid = getReqVal('grid', 0); $tokenType = getReqVal('token_type', 0); if ($grid < 0 || $grid >= count($this->data['grid_list'])) { $this->_rspErr(1, 'paramater error grid'); return; } if (!in_array( $tokenType, array( mt\Shop::TOKEN_TYPE_GOLD, mt\Shop::TOKEN_TYPE_DIAMOND, ) )) { $this->_rspErr(1, 'paramater error token_type'); return; } $gridInfo = &$this->data['grid_list'][$grid]; if ($gridInfo['count'] <= 0) { $this->_rspErr(1, 'goods not enough'); return; } $goodsMeta = mt\Dailyselection::get($gridInfo['id']); if (!$goodsMeta) { $this->_rspErr(1, 'config error grid'); return; } $arrPrice = splitStr1($goodsMeta['price']); $arrTokenType = splitStr1($goodsMeta['token_type']); if (count($arrPrice) != count($arrTokenType)) { $this->_rspErr(1, 'config error price'); return; } if (!in_array( $tokenType, $arrTokenType )) { $this->_rspErr(1, 'paramater error token_type'); return; } $tokenPos = array_search($tokenType, $arrTokenType); if (is_null($tokenPos) || $tokenPos === false) { $this->_rspErr(1, 'paramater error token_pos'); return; } $costItemId = mt\Shop::getCostItemIdByTokenType($tokenType); if ($costItemId <= 0) { $this->_rspErr(1, 'paramater error cost item id'); return; } $costItems = array( array( 'item_id' => $costItemId, 'item_num' => $arrPrice[$tokenPos] ) ); $lackItem = null; if (!myself()->_hasEnoughItems($costItems, $lackItem)) { myself()->_rspErr(2, myself()->_getLackItemErrMsg($lackItem)); return; } $gridInfo['count'] = 0; $this->save(); $awardService = new AwardService(); $propertyChgService = new PropertyChgService(); $propertyChgService->addUserChg(); myself()->_decItems($costItems); myself()->_addItems( array( array( 'item_id' => $goodsMeta['goods_id'], 'item_num' => $goodsMeta['goods_num'], 'is_payed' => true ) ), $awardService, $propertyChgService ); { $event = [ 'name' => LogService::SHOP_BUY_ITEM_DAILY, 'val' => $costItems[0]['item_num'] ]; switch ($tokenType) { case mt\Shop::TOKEN_TYPE_GOLD: { LogService::consumeGold($event); } break; default: { break; } } } myself()->_rspData(array( 'award' => $awardService->toDto(), 'property_chg' => $propertyChgService->toDto() )); } private function internalRefresh($manual) { if ($manual) { $this->data['refresh_time'] = myself()->_getNowTime(); ++$this->data['refresh_count']; } else { $this->data = array( "refresh_time" => myself()->_getNowTime(), "refresh_count" => 0, "grid_list" => array() ); } $this->data['grid_list'] = array(); for ($i = 1; $i <= self::MAX_GRID_ID; $i++) { $rndMeta = mt\Dailyselection::randomBySlot($i); if ($rndMeta) { array_push( $this->data['grid_list'], array( 'id' => $rndMeta['id'], 'count' => 1 ) ); } } } private function load() { $rawData = myself()->_getSelfRedis()->get($this->getRedisKey()); if (empty($rawData)) { $this->internalRefresh(false); $this->save(); return; } $this->data = json_decode($rawData, true); } private function save() { $remainSec = 3600 * 24 - (myself()->_getNowTime() - myself()->_getNowDaySeconds()); $remainSec = $remainSec + rand() % (3600 * 3); $remainSec = max(0, $remainSec); myself()->_getSelfRedis()->set( $this->getRedisKey(), json_encode($this->data) ); myself()->_getSelfRedis()->pexpire( $this->getRedisKey(), $remainSec * 1000); } private function getRedisKey() { $key = DAILY_SELECTION_KEY . myself()->_getTodayLeadStr() . ':' . myself()->_getAccountId(); return $key; } }