* 6.0.0 第六版: 引入currency字段, 增加出海结算支持. 2022.11 * 5.0.0 第五版: 全部动态交易数据存入mysql. 2021.11 * 4.0.0 第四版: 言灵世界 商城模块. 2020.08 * 2.2.0 第三版: 独立的游戏币<元宝>, 面向多渠道的充值模式, 拉起充值成功后, 给玩家发放元宝. 游戏内部消费元宝,钻石和金币.可以用元宝购买金币和钻石.这一版在上面的PayProc中 * 2015年9月23日
* 2.1.0 mn_pay mn_AddUserCash ... 以 mn_ 打头的函数是第二版, 修改为伪托管模式,除了充值的时候跟腾讯通讯,其余时间自己管理游戏币:钻石. * 2015年7月23日
* 2.0.1 m_pay m_AddUserCash ... 以 m_ 打头的函数是第一版, 完全按照应用宝官方要求托管游戏币的模式开发的. * 2015年4月23日
* 1.0.0 Created at 2016-4-20. by --gwang
* @author gwang (mail@wanggangzero.cn) * @copyright © 2016-4-20, SJZ LoyalSoft Corporation & gwang. All rights reserved. */ class PayProc { const orderTab = 'tab_order_tab'; /** * 逻辑分发 * 所有的Proc中必须有这样一个方法 */ public static function procMain() { switch (req()->cmd) { // 支付相关的活动 case CmdCode::cmd_pay_getfirstpaygift: # 8802 领取首充礼包 return PayProc::m_GetFirstPayGift(); case CmdCode::cmd_pay_resetFirstRechargeUI_OpenTip: # 8803 重置弹框 return PayProc::resetFirstRechargeUI_OpenTip(); case CmdCode::cmd_pay_accumulateRechargeRewardReceived: # 8804 累计充值领取奖励 return PayProc::accumulateRechargeRewardReceived(); // 游戏内二级货币消费 case CmdCode::cmd_mpay_pay: # 8807 消费.. return self::m_pay(); # ::==> 购买普通商城物品 case CmdCode::cmd_mpay_buyDynamic: # 8809 购买动态商城物品 return self::m_pay_buyDynamic(); case CmdCode::cmd_mpay_getDynamic: # 8810 刷新神秘商城物品 return self::m_pay_getDynamic(); // 充值消费 case CmdCode::cmd_mpay_get_balance: # 8808 刷新账号余额 return self::m_refreshChargeOrders(); # ::==> 刷新订单-领取充值金额 case CmdCode::cmd_mpay_selfCheckOrders: # 8811 自助检查异常订单 return self::selfhelpCheckOrders(); case CmdCode::cmd_mpay_getPayRecords: # 8812 查询订单记录 return self::GetPayRecoreds(); case CmdCode::cmd_mpay_PayDeliverGoods: # 8813 查询订单并发货 return self::PayDeliverGoods(); case CmdCode::cmd_mpay_UserRechargeDrawPrize: # 8814 充值领奖励 2022.10 return self::UserRechargeDrawPrize(); case CmdCode::cmd_mpay_NewFirstRecharge: # 8815 新首充功能 2022.10 return self::NewFirstRecharge(); default: return Resp::err(ErrCode::cmd_err); } } /** * 8804 累计充值 */ static function accumulateRechargeRewardReceived() { list($id) = req()->paras; $mo = GameConfig::accumulaterecharge_getItem($id); # 用yuanbao做的key my_Assert($mo != null, ErrCode::err_const_no); my_Assert(ctx()->baseInfo->accumulateYuanBao >= $id, ErrCode::pay_accumulateYuanBaoNotEnough); my_Assert(!in_array($id, ctx()->privateState->accumulateRechargeRewardRecord), ErrCode::pay_repeatReceive); ctx()->privateData(true)->accumulateRechargeRewardRecord[] = $id; StoreProc::AddMultiItemInStore($mo->reward); $reset = true; $dic = GameConfig::accumulaterecharge(); $max_yuanbao = 0; foreach ($dic as $aMo) { if (!in_array($aMo->yuanbao, ctx()->privateState->accumulateRechargeRewardRecord)) { $reset = false; } if ($aMo->yuanbao > $max_yuanbao) { $max_yuanbao = $aMo->yuanbao; } } if ($reset) { ctx()->privateData(true)->accumulateRechargeRewardRecord = array(); ctx()->baseInfo->accumulateYuanBao -= $max_yuanbao; if (ctx()->baseInfo->accumulateYuanBao <= 0) { ctx()->baseInfo->accumulateYuanBao = 0; } } UserProc::updateUserInfo(); return Resp::ok(array('gold' => ctx()->baseInfo->gold, 'cash' => ctx()->baseInfo->cash, 'tili' => ctx()->baseInfo->tili, 'tili_ts' => ctx()->baseInfo->tili_ts, 'accumulateYuanBao' => ctx()->baseInfo->accumulateYuanBao, 'store' => ctx()->store, 'privateState' => ctx()->privateState, 'reward' => StoreProc::$reward, 'reward_Gem' => StoreProc::$reward_Gem, 'reward_equip' => StoreProc::$reward_equip, )); } /** * 8803 重置弹框 */ static function resetFirstRechargeUI_OpenTip() { ctx()->privateData(true)->firstRechargeUI_OpenTip = 0; UserProc::updateUserInfo(); return Resp::ok(); } static $retArr; /** * 8815 新首冲功能5点前不能领取奖励,则该请求只是为了首充开发界面时获得最新时间戳 */ static function NewFirstRecharge() { UserProc::updateUserInfo(); return Resp::ok(array( "ret" => 'true', )); } /** * [8814]领取奖励 (新版2021) */ static function UserRechargeDrawPrize() { list($type, $typeId) = req()->paras; $user = ctx(); self::$retArr = array(); switch ($type) { case Enum_Recharge::FirstRecharge://首冲 my_Assert($user->pay->firstRechage == 0, ErrCode::shop_firstRechargeNotRepeat); StoreProc::AddMultiItemInStore(GameConfig::globalsettings()->firstRechargePrizes); $user->pay->firstRechage = 1; self::$retArr[] = GameConfig::globalsettings()->firstRechargePrizes; break; case Enum_Recharge::DaliySpecialPackages://每日特惠 my_Assert(!in_array($typeId, $user->shopdata->daliySpecialPackages), ErrCode::shop_daliySpecialRewardNotRepeat); $mo = GameConfig::shop_limit_getItem($typeId); my_Assert($mo != null, ErrCode::err_const_no); if ($mo->price != 0) {//购买60元7天特惠,则不是免费的礼包现在也可以领取。这里校验一下 //my_Assert($user->shopdata->daliySpecial_ts!= 0, ErrCode::shop_daliySpecialRewardNotRepeat); $ts = $user->shopdata->daliySpecial_ts + 7 * 24 * 60 * 60; my_Assert(now() < $ts, ErrCode::shop_daliySpecialRewardNotRepeat); } $itemid = explode(',', $mo->reward)[0]; $itemMO = GameConfig::item_package_getItem($itemid); my_Assert(null != $itemMO, ErrCode::err_const_no); StoreProc::AddMultiItemInStore($itemMO->contents); self::$retArr[] = $itemMO->contents; $shopdata = new Info_UserShop(ctx()->shopdata); $shopdata->daliySpecialPackages[] = $typeId; ctx()->shopdata = $shopdata; break; case Enum_Recharge::RechargeRebate://充值返利 $mo = GameConfig::rechargeRebate_getItem(3, $typeId); my_Assert($mo != null, ErrCode::err_const_no); my_Assert($user->baseInfo->charge_amt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough); my_Assert(!in_array($typeId, $user->shopdata->rechargeRebateRewardsList), ErrCode::shop_RechargeRebateRewardNotRepeat); StoreProc::AddMultiItemInStore($mo->rewards); self::$retArr[] = $mo->rewards; break; case Enum_Recharge::LimitBuy://限购中免费礼包领取 $packageCfg = GameConfig::shop_limit_getItem($typeId); my_Assert(null != $packageCfg, ErrCode::err_const_no); my_Assert($packageCfg->price == 0, ErrCode::shop_limit_NotFree); self::checklimitBuyRecharge($typeId); break; case Enum_Recharge::Accumulate: # 累充, gwang 2022.10.18 // list($amount, $day) = explode('-', $typeId); # 拆分key1,key2 // $cfg = GameConfig::shop_accumulating_getItem($amount, $day); # 配置对象 // my_Assert(null != $cfg, ErrCode::err_const_no); # 防御null // // $acc = new Ins_Accumulate($user->shopdata->shopAccumulateData); # 累充对象 // my_Assert(!$acc->IsDrawed($amount, $day), ErrCode::active_hasgetted); # 防御: 已经领取 // my_Assert($user->baseInfo->rechargeFun_amt >= $cfg->amount, "累充金额不足!"); # 校验: 金额 // my_Assert($acc->EndDay() >= tsDay(), "领取时间已过!"); # 校验: 时间 // StoreProc::AddMultiItemInStore($cfg->goods); # 发放奖品 // $user->shopdata->shopAccumulateData = $acc->SetDrawd($amount, $day); # 更新数据 // self::$retArr[] = $cfg->goods; $mo = GameConfig::rechargeRebate_getItem(Enum_Recharge::Accumulate, $typeId); my_Assert($mo != null, ErrCode::err_const_no); my_Assert($user->baseInfo->charge_amt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough); my_Assert(!in_array($typeId, $user->shopdata->rechargeRebateRewardsList), ErrCode::shop_RechargeRebateRewardNotRepeat); $user->shopdata->rechargeRebateRewardsList[] = $typeId; StoreProc::AddMultiItemInStore($mo->rewards); self::$retArr[] = $mo->rewards; break; case Enum_Recharge::FirstRecharge_new: $mo = GameConfig::shop_accumulating_getItem($typeId); my_Assert(null != $mo, ErrCode::err_const_no); $shopdata = new Info_UserShop(ctx()->shopdata); $amount = $mo->amount; if (!StlUtil::dictHasProperty($shopdata->fRechargeRecord, $amount)) { $shopdata->fRechargeRecord->$amount = array(); } my_Assert(!in_array($typeId, $shopdata->fRechargeRecord->$amount), ErrCode::active_FirstRechargeRewardRepeat); $shopdata->fRechargeRecord->$amount[] = $typeId; StoreProc::AddMultiItemInStore($mo->goods); # 发放奖品 ctx()->shopdata = $shopdata; self::$retArr[] = $mo->goods; break; case Enum_Recharge::DayAccumulateRecharge: #每周累计金额奖励 $mo = GameConfig::rechargeRebate_getItem($type, $typeId); my_Assert($mo != null, ErrCode::err_const_no); my_Assert($user->shopdata->dayRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough); my_Assert(!in_array($typeId, $user->shopdata->dayRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat); $user->shopdata->dayRechargeReceived[] = $typeId; // if ($rechargeType == 1) { // my_Assert($user->shopdata->dayRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough); // my_Assert(!in_array($rmb, $user->shopdata->dayRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat); // $user->shopdata->dayRechargeReceived[] = $rmb; // } else if($rechargeType == 2){ // my_Assert($user->shopdata->weekRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough); // my_Assert(!in_array($rmb, $user->shopdata->weekRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat); // $user->shopdata->weekRechargeReceived[] = $rmb; // } StoreProc::AddMultiItemInStore($mo->rewards); self::$retArr[] = $mo->rewards; break; case Enum_Recharge::WeekAccumulateRecharge: #每周累计金额奖励 $mo = GameConfig::rechargeRebate_getItem($type, $typeId); my_Assert($mo != null, ErrCode::err_const_no); my_Assert($user->shopdata->weekRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough); my_Assert(!in_array($typeId, $user->shopdata->weekRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat); $user->shopdata->weekRechargeReceived[] = $typeId; StoreProc::AddMultiItemInStore($mo->rewards); self::$retArr[] = $mo->rewards; break; default: break; } ctx($user); UserProc::updateUserInfo(); return Resp::ok(array( "ret" => self::$retArr, "pay" => $user->pay, "shopdata" => ctx()->shopdata, "base" => $user->baseInfo, "store" => $user->store, )); } /** * 限购礼包--终身礼包--套装礼包--校验 * @param type $packageId */ private static function checklimitBuyRecharge($packageId) { # 参数; 礼包id $shopdata = new Info_UserShop(ctx()->shopdata); $packageCfg = GameConfig::shop_limit_getItem($packageId); my_Assert(null != $packageCfg, ErrCode::err_const_no); $arr = array(); if ($packageCfg->goodsType == Enum_Recharge::LifelongGift) { $shopdata->lifelongGiftReceived[] = $packageId; $arr = $shopdata->lifelongGiftReceived; } elseif ($packageCfg->goodsType == Enum_Recharge::SuitGift) { $ts = now() - $shopdata->suitGiftStartTs; my_Assert($ts <= $packageCfg->limit_ts, ErrCode::shop_limit_TsMax); # 校验时间 $shopdata->suitGiftReceived[] = $packageId; $arr = $shopdata->suitGiftReceived; } else { switch ((int) $packageCfg->subType) { case 1: $shopdata->purchasedDailyLimitPackages[] = $packageId; $arr = $shopdata->purchasedDailyLimitPackages; break; case 2: $shopdata->purchasedWeeklyLimitPackages[] = $packageId; $arr = $shopdata->purchasedWeeklyLimitPackages; break; case 3: $shopdata->purchasedMonthlyLimitPackages[] = $packageId; $arr = $shopdata->purchasedMonthlyLimitPackages; break; default: Err(ErrCode::err_innerfault); } } $hasN = count(array_filter($arr, function ($val)use ($packageId) { # 计数:筛选条件 return $val == $packageId; })); my_Assert($hasN <= $packageCfg->limit_num, ErrCode::shop_limit_max); # 校验购买数量 $itemid = explode(',', $packageCfg->reward)[0]; # 奖励礼包Id $itemMO = GameConfig::item_package_getItem($itemid); my_Assert(null != $itemMO, ErrCode::err_const_no); $err = StoreProc::AddMultiItemInStore($itemMO->contents); # 发放奖励 self::$retArr[] = $itemMO->contents; my_Assert(ErrCode::ok == $err, $err); ctx()->shopdata = $shopdata; # 回写数据 } /** * [8813] 充值发货 (新版2021) */ static function PayDeliverGoods() { list($cpOrderId) = req()->paras; $result = pay_op::CheckAndDrawOrder(req()->uid, $cpOrderId, array(new PayProc, 'distributePayGoods')); CLog::pay($result); my_Assert($result->err == 0, $result->err); # 发货失败 $user = ctx(); NormalEventProc::OnPaySuccess(); UserProc::updateUserInfo(); # 回写玩家数据 return Resp::ok(array( "ret" => self::$retArr, # # 奖励串 "mod" => $result->result, # # 商品刷新模块名 "baseInfo" => $user->baseInfo, // "shopdata" => $user->shopdata, "store" => $user->store, 'task' => ctx()->task, 'heros' => ctx()->heros, 'privateState' => $user->privateState, )); } /** * 发货 * @param \loyalsoft\pay\dbOrder $order * @return bool */ static function distributePayGoods($order = null) { my_Assert($order->product_id != null, ErrCode::pay_order_product_id); $user = ctx(); self::$retArr = array(); $shopItem = GameConfig::shop_getItem($order->product_id); # 商城总表中查找下配置数据 $mod = ""; if (null != $shopItem) { $mod = $shopItem->shopItemType; switch ($shopItem->shopItemType) { case 'cash': # 充值二级货币 $cashMo = GameConfig::shop_cash_getItem($shopItem->shopItemTypeId); my_Assert(null != $cashMo, ErrCode::err_const_no); // StoreProc::AddMultiItemInStore($cashMo->reward, "付费"); self::$retArr[] = ShopProc::BuyShop_Cash(EnumShopGift::Cash_Shop, $shopItem->shopItemTypeId, $order->product_count); break; case 'monthcard': # 月卡 $monthCardMo = GameConfig::shop_monthcard_getItem($shopItem->shopItemTypeId); my_Assert(null != $monthCardMo, ErrCode::err_const_no); ShopProc::BuyShop_MonthCard(EnumShopGift::MonthCard_Shop, $shopItem->shopItemTypeId, $order->product_count); break; case 'battlePass_gate': ctx()->privateData(true)->battlePass_gate_cost_ts = now(); break; case 'battlePass_activePoint': ctx()->privateData(true)->battlePass_activePoint_cost_ts = now(); break; case 'battlePass_tili': ctx()->privateData(true)->battlePass_tili_cost_ts = now(); break; case 'box': case 'daily': case 'gategift': case 'gold': case 'junbei': case 'supply' : default: my_Assert(false, "该道具并非现金充值类!"); break; } } $user->baseInfo->charge_amt += $order->amount; # 统计下累充金额 if ($order->amount > 0) { if (ctx()->privateState->firstRecharge_receiveTag == 0) { ctx()->privateState->firstRechargeUI_OpenTip = 1; ctx()->privateState->firstRecharge_receiveTag = 1; } // if (ctx()->privateState->firstRecharge_receiveTag < 1) { // ctx()->privateState->firstRecharge_receiveTag = 1; // } } ctx($user); return [true, $mod]; } static function suitGiftCheck() { $shopdata = new Info_UserShop(ctx()->shopdata); $cost = 0; $dic = GameConfig::shop_accumulating(); foreach ($dic as $k => $item) { if ($cost <= $item->amount) { $cost = $item->amount; } } if (StlUtil::dictHasProperty($shopdata->fRechargeTime, $cost)) { if ($shopdata->suitGiftStartTs == 0) { $shopdata->suitGiftStartTs = now(); } } else { $shopdata->suitGiftStartTs = 0; } ctx()->shopdata = $shopdata; } static function checkAmount($order) { my_Assert($order->product_id != null, ErrCode::pay_order_product_id); if ($order->product_id >= 6 && $order->product_id <= 1000) {//充值表 $mo = GameConfig::recharge_getItem($order->product_id); my_Assert($mo != null, ErrCode::err_const_no); my_Assert($order->amount == $mo->rmd, ErrCode::pay_price_err); } elseif ($order->product_id >= 801001 && $order->product_id <= 801999) {//限购 //该功能暂时没有开发 } elseif ($order->product_id >= 804001 && $order->product_id <= 804999) {//每日特惠 $mo = GameConfig::shop_limit_getItem($order->product_id); my_Assert($mo->price == $order->amount, ErrCode::pay_price_err); } elseif ($order->product_id >= 805001 && $order->product_id <= 805999) {//限时 //该功能暂时没有开发 } elseif ($order->product_id >= 901001 && $order->product_id <= 999999) {//月卡 $packageCfg = GameConfig::shop_monthVIP_getItem($order->product_id); my_Assert(null != $packageCfg, ErrCode::err_const_no); my_Assert($packageCfg->price == $order->amount, ErrCode::pay_price_err); } return true; } /** * 礼包有了的第一次登录记录 */ static function SuitGiftTsRecord() { $shopdata = new Info_UserShop(ctx()->shopdata); if (!StlUtil::dictHasProperty($shopdata, 'suitGiftStartTs')) { $shopdata->suitGiftStartTs = 0; } if ($shopdata->suitGiftStartTs == 0) { $shopdata->suitGiftStartTs = now(); } ctx()->shopdata = $shopdata; } /** * 8812 查询充值记录 */ static function GetPayRecoreds() { $uid = req()->uid; $arr = daoInst()->select(" cpOrderId as '订单' ,product_name as '道具',amount as '金额' ,from_unixtime(order_ts) as '时间' ")->from(self::orderTab) ->where("uid")->eq($uid) ->andWhere("status")->eq(1) ->fetchall(); return Resp::ok($arr); } // // /** * 刷新充值订单(领取充值结果) * @deprecated since version 2024.12.20 */ public static function m_refreshChargeOrders() { # 客户端参数解析 $uid = req()->uid; # userID $zoneid = req()->zoneid; # 分区Id if (count(req()->paras) <= 0) { # 参数为空, 执行自检逻辑 return self::selfhelpCheckOrders(); } $cpOrderId = req()->paras[0]; # 后台订单编号 if (!$uid || ($zoneid < 1) || strlen($cpOrderId) != 16) { # 订单编号长16位 return Resp::err(ErrCode::paras_err); } $order = daoInst()->select()->from(self::orderTab) # 取订单数据 ->where('cpOrderId')->eq($cpOrderId) ->limit(1)->fetch(); if (!$order) { // var_dump($order); CLog::pay(' 订单不存在! ' . $cpOrderId); return Resp::err(ErrCode::pay_order_no); } if (false === strpos($uid, $order->uid)) { # UID不符 return Resp::err(ErrCode::pay_order_uid); } if ($order->status != 1) { CLog::pay(' 订单尚未完成支付!'); return Resp::err(ErrCode::pay_order_paystatus); } if ($order->drawed_ts > 0) { # 定单已经发过货了 CLog::pay(' 订单重复请求发货!' . $cpOrderId); return Resp::err(ErrCode::pay_order_drawed); } // 准备发货 $product_id = $order->product_id; $product_count = $order->product_count; $typid = substr("$product_id", 0, 3); # 提取商品编号前缀 switch ($typid) { case '802': # 神秘商城物品 $item = GameConfig::secretshop_typeId_getItem($product_id); break; case '801': # 商城物品 $item = GameConfig::shop_getItem($product_id); break; default : return Resp::err(ErrCode::pay_systembusy_err); } my_Assert(isset($item), ErrCode::pay_shopItem_cosnt_goods_err); if ($item->pricetype != 0) { CLog::pay(" 道具付费类型异常:" . $product_id); return Resp::err(ErrCode::pay_m_type_err); } for ($i = 0; $i < $product_count; $i++) { # 默认为1,还没有设计为n的情况 StoreProc::AddMultiItemInStore($item->goods, 5); # 发货 } $n = daoInst()->update(self::orderTab) ->data(array('drawed_ts' => now())) ->where('cpOrderId')->eq($cpOrderId) ->exec(); my_Assert($n > 0, ErrCode::err_db); # 数据库操作失败 ctx()->baseInfo->charge_amt += $order->amount; # 历史充值记录(单位分) UserProc::updateUserInfo(); # 更新玩家数据信息 Event::trigger('pay', array('amt' => $order->amount)); # 触发充值事件 CLog::pay("订单发货成功: $cpOrderId"); return Resp::ok(# 返回 array('cash' => ctx()->baseInfo->cash, # # 直接将游戏币的最新值返回给客户端 'charge_amt' => ctx()->baseInfo->charge_amt, # 充值总记录 'store' => ctx()->store, # # 背包 'goods' => $item->goods, # # 发货内容 'count' => $product_count, # # 发货数量 ) ); } /** * 检查删档内测订单 */ static function checkDeltest() { $uid = req()->uid; if (ctx()->privateState->deltest == 1) { $orders = daoInst()->select()->from('tpl_order_tab_deltest') ->where('uid')->eq($uid) ->andwhere('status')->eq(1) ->fetchall(); if (count($orders) > 0) { # 有充值记录 foreach ($orders as $order) { // 翻倍发放砖石 isEditor() and $order = new pay\dbOrder(); $rmb = intval($order->amount / 100); # 计算充值金额(元) EmailProc::SendDelTestMail(req()->zoneid, $uid, $rmb); CLog::pay(req()->uid . '发送删档内侧补偿邮件' . $order->cpOrderId); } } ctx()->privateData(true)->deltest = 0; } // CLog::pay('删档内测补偿检查'); } /** * [8811] 检查异常订单, 补发道具 */ public static function selfhelpCheckOrders() { $uid = req()->uid; $orders = daoInst()->select() ->from(self::orderTab) ->where('uid')->eq($uid) ->andWhere('status')->eq(1) ->andWhere('drawed_ts')->le(0) ->fetchAll(); if (count($orders) > 0) { foreach ($orders as $order) { $result = pay_op::CheckAndDrawOrder(req()->uid, $order->cpOrderId, array(new PayProc, 'distributePayGoods')); CLog::pay($result); my_Assert($result->err == 0, $result->err); # 发货失败 UserProc::updateUserInfo(); # 回写玩家数据 CLog::pay(req()->uid . ' 登录补发订单 ' . $order->cpOrderId); } } return Resp::ok(array( "ret" => self::$retArr, # # 奖励串 "mod" => '', # # 商品刷新模块名 "baseInfo" => ctx()->baseInfo, // "shopdata" => $user->shopdata, "store" => ctx()->store, 'task' => ctx()->task, 'heros' => ctx()->heros, 'privateState' => ctx()->privateState, )); // return Resp::ok('ok'); # everything is ok! } // // // /** * 8810 免费或利用【游戏内货币】获取神秘商城物品 * 刷新规则: 根据玩家拥有的英雄、装备、道具等数据进行刷新。(因英雄、道具、装备数量不足以支撑该刷新规则,目前先按照随机刷新做,几率平等) */ public static function m_pay_getDynamic() { $user = ctx(); $userSecretshop = new Info_UserSecretshop($user->userSecretshop); // 参数提取 $refreshType = req()->paras[0]; # 刷新类型(参数)0,不刷,1,免费刷,2,钻石刷 switch ($refreshType) { case 1: # 免费刷 if (now() < $userSecretshop->lastRefreshTs + glc()->secretshop_refresh_interval) { // 检查是否达到免费刷新时间了, 执行自动更新 return Resp::err(ErrCode::pay_secretshopt_freeRefresh_Time); } break; case 2: # 钻石刷 if (glc()->secretshop_refresh_maxtimes <= $userSecretshop->refreshedTimes) { // 检查刷新次数, 已达上限, 返回错误信息 return Resp::err(ErrCode::pay_refresh_times); } # 可以继续刷新, $cishu = $userSecretshop->refreshedTimes + 1; # 下次 $amt = GameConfig::secretshop_refresh_getItem($cishu)->price; if (!$user->base(true)->Consume_Cash($amt)) { # 扣除本次所需费用, 余额不足, 返回错误信息 return Resp::err(ErrCode::notenough_cash_msg); } $userSecretshop->refreshedTimes++; # 增加当天付费刷新计数 break; case 0: # 不刷 default : # 默认不刷 // do nothing. break; } if ($refreshType != 0) { # 是否刷新 $err = self::refreshDynamicShopItems($userSecretshop); # 更新物品表 if ($err) { return Resp::err($err); } $user->userSecretshop = $userSecretshop; ctx($user); UserProc::updateUserInfo(); } // 返回最新物品表 return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端 'gold' => $user->baseInfo->gold, 'tili' => $user->baseInfo->tili, 'cash' => $user->baseInfo->cash, 'uss' => $userSecretshop, # # 当前神秘商城数据 )); } /** * 更新神秘商城物品 * @param Info_UserSecretshop $userSecretshop Description */ private static function refreshDynamicShopItems(&$userSecretshop) { $userSecretshop->lastRefreshTs = now(); // todo: 这里补完更新物品的函数, // 第一版: 随机 $userSecretshop->currentItems = ObjectInit(); for ($i = 1; $i <= 3; $i++) { # 3种类型的商品 $arr = GameConfig::secretshop_goodsType_getItem($i); if (count($arr) > 0) { $err = self::Dice(GameConfig::secretshop_goodsType_getItem($i), 1, $userSecretshop); # 一个种类一次1个物品 if ($err) { return $err; } } } return ErrCode::ok; } /** * 投骰子 * @param assoc_array $arr 奖池物品 * @param int $number 提取数量 * @return string itemid,num;itemid,num;... */ private static function Dice($arr, $number, &$userSecretshop) { $max = 0; # 计算物品权重总和 array_walk($arr, function ($value) use (&$max) { $max += $value->probability; }); if (!$max) { # 配置数据有问题 return ErrCode::err_const_no; } for ($i = 0; $i < $number; $i++) { $rnd = CommUtil::random(1, $max); # 投骰子 $start = 0; $rew = null; foreach ($arr as $item) { # 循环判断落入那个物品上 if (CommUtil::isPropertyExists($item, 'probability') // # && $start < $rnd && $rnd <= $start + $item->probability) { # 落入区间 $rew = $item; # 记录物品 break; } $start += $item->probability; # 继续判断是否落入下一物品的区间 } # foreach end if (!$rew) { return ErrCode::lottery_noselecteditem; } $id = $rew->typeId; $userSecretshop->currentItems->$id = 0; } # for end return ErrCode::ok; } /** * 清理每日各种上限 */ private static function clearDailyLimits() { $userSecretshop = new Info_UserSecretshop(ctx()->userSecretshop); $userSecretshop->refreshedTimes = 0; ctx()->userSecretshop = $userSecretshop; } /** * [8809]【游戏内货币】购买神秘商城物品 * 规则: 商城物品会刷新 */ public static function m_pay_buyDynamic() { $user = new Data_UserGame(ctx()); $userSecretshop = new Info_UserSecretshop($user->userSecretshop); $itemId = req()->paras[0]; # 商品id (点一次购买一个) $num = 1; # 暂时固定为一次购买一个 # my_Assert(CommUtil::isPropertyExists($userSecretshop->currentItems, $itemId), ErrCode::pay_secretshop_noitem_err); $cishu = $userSecretshop->currentItems->$itemId; # 购买次数 my_Assert($cishu < glc()->secretshop_itembuy_maxtimes, ErrCode::pay_secretshop_buytimes); # 判断购买次数 $shopItem = GameConfig::secretshop_typeId_getItem($itemId); # 常量数据 $amt = $shopItem->price * pow(2, $cishu); # 计算价格 switch ($shopItem->pricetype) { case 1: my_Assert($user->base(true)->Consume_Cash($amt), ErrCode::notenough_cash_msg); # 扣除钻石 break; case 2: my_Assert($user->base(true)->Consume_Gold($amt), ErrCode::notenough_gold_msg); # 扣除金币 break; default : return Resp::err(ErrCode::pay_m_type_err); } // 道具解包/发货 $err = self::expendSecretShopItem($shopItem, $num); # 发放商品 if ($err != ErrCode::ok) { # 发货失败 return Resp::err($err); } $userSecretshop->currentItems->$itemId += 1; # 购买次数+1 $user->userSecretshop = $userSecretshop; ctx($user); UserProc::updateUserInfo(); # 回写数据 // StatProc::secretShopbuy($req->zoneid, $req->uid, $itemId, $num); # 统计/监控数据 return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端 'gold' => $user->baseInfo->gold, 'tili' => $user->baseInfo->tili, 'cash' => $user->baseInfo->cash, 'store' => $user->baseInfo->store, # # 背包,(装备、碎片、。。) 'heros' => $user->baseInfo->heros # # 角色 )); // } /** * [8807]【游戏内货币】购买普通商城物品 */ public static function m_pay() { $user = ctx(); # user引用 my_Assert(count(req()->paras) >= 3, ErrCode::parasnotenough_msg); # 参数不足 list($paytype, $itemId, $num) = req()->paras; # 付费类型, 1.钻石, 2.金币 ,道具ID ,数量, 默认为1 my_Assert($num >= 1, ErrCode::paras_err); # 参数非法, $shopItem = GameConfig::shop_getItem($itemId); # 取商品的常量数据 my_Assert(isset($shopItem), ErrCode::err_const_no); # 检测是否存在道具的常量数据 my_Assert($shopItem->pricetype == $paytype, ErrCode::pay_price_err); # 商品定价类型检查 $amt = $shopItem->price; # 道具价格(钻石) my_Assert($amt > 0, ErrCode::pay_price_err); # 商品定价数值检查 $bDeal = false; # 成交标志位 switch ($paytype) { # 1. 钻石, 2. 金币, other:非法 case 1: # 钻石 $bDeal = ctx()->base(true)->Consume_Cash($amt); # 更新(扣除)玩家游戏币(钻石)余额 my_Assert($bDeal, ErrCode::notenough_cash_msg); # 防范扣除失败 break; case 2: # 金币 $bDeal = $user->base(true)->Consume_Gold($amt * $num); # 更新玩家金币余额 my_Assert($bDeal, ErrCode::notenough_gold_msg); # 防范扣除失败 break; default : # 未知的支付类型 return Resp::err(ErrCode::pay_m_type_err); } my_Assert($bDeal, ErrCode::err_innerfault); # 交易失败 $err = self::expendShopItem($shopItem, $num); # 发放商品(普通商城只有金币和体力) my_Assert(ErrCode::ok == $err, $err); # 防范发货失败 UserProc::updateUserInfo(); # 回写数据 // StatProc::shopbuy($zoneid, $uid, $itemId, $num); # 统计/监控数据 return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端 'gold' => $user->baseInfo->gold, 'tili' => $user->baseInfo->tili, 'cash' => $user->baseInfo->cash, 'store' => $user->store )); } /** * 解包商城物品并发货 * @param sm_Shop $shopItem * @param int $num 数量 */ private static function expendShopItem($shopItem, $num) { for ($i = 0; $i < $num; $i++) { $err = StoreProc::AddMultiItemInStore($shopItem->goods, '商城'); my_Assert(ErrCode::ok == $err, $err); } return ErrCode::ok; } /** * 道具解包并发货(神秘商城) * @param sm_secretshop $shopItem * @param type $num */ private static function expendSecretShopItem($shopItem, $num) { for ($i = 0; $i < $num; $i++) { $err = StoreProc::AddMultiItemInStore($shopItem->goods, '神秘商城'); if ($err) { return $err; } } return ErrCode::ok; } // // // // /** * [8802] 领取首付礼包 */ public static function m_GetFirstPayGift() { //list($day) = req()->paras; // $itemId = glc()->FirstPay_ItemId; // $privateState = ctx()->privateState; // // if (CommUtil::isPropertyExists($privateState, "firstPayGift") # // && $privateState->firstPayGift) { # 如果已经领取首付礼包 // return Resp::err(ErrCode::pay_firstpaygetted); // } // my_Assert(ctx()->baseInfo->charge_amt > 0, ErrCode::pay_firstpayno_err); # 如果尚未完成首付 // // $itemModel = GameConfig::shop_getItem($itemId); # 取商品常量 // if ($itemModel == null) { # 检测首付礼包是否存在 // return Resp::err(ErrCode::err_const_no); // } // ctx()->privateState->firstPayGift = true; # 设置首付标志 my_Assert(ctx()->baseInfo->charge_amt != 0, ErrCode::pay_firstpayno_err); //my_Assert(!in_array($day, ctx()->privateState->firstRechargeRewardRecord), ErrCode::pay_repeatReceive); // $ts = TimeUtil::totalDays(ctx()->privateState->firstRechargeTs); // $sTs = $ts + $day -1; // my_Assert(TimeUtil::totalDays() >= $sTs, ErrCode::pay_rewardReceive_ts_limit); for ($i = 1; $i <= ctx()->privateState->firstRecharge_receiveTag; $i++) { if (!in_array($i, ctx()->privateState->firstRechargeRewardRecord)) { ctx()->privateData(true)->firstRechargeRewardRecord[] = $i; $mo = GameConfig::firstrecharge_reward_getItem($i); my_Assert($mo != null, ErrCode::err_const_no); StoreProc::AddMultiItemInStore($mo->reward); # 发放首付礼包到玩家仓库 } } ctx()->privateData(true)->firstRechargeUI_OpenTip = 0; UserProc::updateUserInfo(); # 更新玩家数据 return Resp::ok(array('gold' => ctx()->baseInfo->gold, 'cash' => ctx()->baseInfo->cash, 'tili' => ctx()->baseInfo->tili, 'tili_ts' => ctx()->baseInfo->tili_ts, 'accumulateYuanBao' => ctx()->baseInfo->accumulateYuanBao, 'store' => ctx()->store, 'privateState' => ctx()->privateState, 'reward' => StoreProc::$reward, 'reward_Gem' => StoreProc::$reward_Gem, 'reward_equip' => StoreProc::$reward_equip, 'heros' => ctx()->heros, )); } public static function setFirstRechargeLoginTag() { if (ctx()->baseInfo->charge_amt == 0) { return; } if (ctx()->privateState->firstRecharge_receiveTag == 3) { return; } if (ctx()->privateState->firstRecharge_receiveTag < 1) { return; } ctx()->privateData(true)->firstRecharge_receiveTag += 1; } // // // // }