props.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <?php
  2. defined('IN_WEB') or die( 'Include Error!');
  3. /**
  4. * 用户道具
  5. */
  6. class ModelProps {
  7. private $_propsIdList = [];
  8. public function __construct(){
  9. }
  10. public function getPropsConfig(){
  11. if(empty($this->_propsIdList)){
  12. $this->_propsIdList = oo::cfg('props');
  13. }
  14. return $this->_propsIdList;
  15. }
  16. /**
  17. * 获取用户的道具
  18. * @param uid 用户uid
  19. * @param id 道具ID
  20. * @return mixed 返回用户道具数组,引用方式
  21. */
  22. public function getUserProps($uid, $id = 0) {
  23. $propsConfig = $this->getPropsConfig();
  24. $outs = [];
  25. if($id != 0){
  26. if (!$uid || !in_array($id,array_keys($propsConfig))){
  27. return [];
  28. }
  29. $propsInfo = self::getUserPropsData($uid, $id);
  30. if(!empty($propsInfo) && $propsInfo['count'] > 0){
  31. $propsInfo['props'] = $propsConfig[$id];
  32. $out = $this->checkStatus($uid,$propsInfo);
  33. $outs = [
  34. "id"=>$out['id'],
  35. "count"=>$out['count'],
  36. "props"=>$propsInfo['props'],
  37. "value"=>null,
  38. ];
  39. }
  40. }else{
  41. $propsInfo = self::getUserPropsData($uid);
  42. if(!empty($propsInfo)){
  43. foreach ($propsInfo as $key=>$row){
  44. if($row['count'] > 0){
  45. $temp = $row;
  46. $temp['props'] = $propsConfig[$row['id']];
  47. $checkData = $this->checkStatus($uid,$temp);
  48. if($checkData){
  49. $outs[] = [
  50. "id"=>$checkData['id'],
  51. "count"=>$checkData['count'],
  52. "props"=>$checkData['props'],
  53. "value"=>null,
  54. ];
  55. }
  56. }
  57. }
  58. }
  59. }
  60. return $outs;
  61. }
  62. public function getUserProps2($uid, $id = 0) {
  63. $propsConfig = $this->getPropsConfig();
  64. $out = [];
  65. if($id != 0){
  66. if (!$uid || !in_array($id,array_keys($propsConfig))){
  67. return [];
  68. }
  69. $propsInfo = self::getUserPropsData($uid, $id);
  70. if(!empty($propsInfo) && $propsInfo['count'] > 0){
  71. $propsInfo['props'] = $propsConfig[$id];
  72. $out = $this->checkStatus($uid,$propsInfo);
  73. }
  74. }else{
  75. $propsInfo = self::getUserPropsData($uid);
  76. if(!empty($propsInfo)){
  77. foreach ($propsInfo as $key=>$row){
  78. if($row['count'] > 0){
  79. $temp = $row;
  80. $temp['props'] = $propsConfig[$row['id']];
  81. $checkData = $this->checkStatus($uid,$temp);
  82. if($checkData){
  83. $out[] = $checkData;
  84. }
  85. }
  86. }
  87. }
  88. }
  89. return $out;
  90. }
  91. /**
  92. * 检测道具过期时间
  93. * @param $uid
  94. * @param $data
  95. * @return mixed
  96. * Created by: Owen
  97. * Created on: 2021/1/25 15:53
  98. */
  99. public function checkStatus($uid,$data){
  100. if($data['id'] == 37){
  101. $curTime = time();
  102. $spins = max(intval(oo::commonOprRedis("common")->ttl(okeys::PropsExpire($uid,"37-spins"))),0);
  103. $coins = max(intval(oo::commonOprRedis("common")->ttl(okeys::PropsExpire($uid,"37-coins"))),0);
  104. if($coins > 0 || $spins > 0){
  105. $data['value'] = [
  106. 'spins' => [
  107. 'time' => $curTime + $spins,
  108. 'buyTimes' => $spins == 0 ? 1 : 0,
  109. 'totalTimes' => 1,
  110. ],
  111. 'coins' => [
  112. 'time' => $curTime + $coins,
  113. 'buyTimes' => $coins == 0 ? 1 : 0,
  114. 'totalTimes' => 1,
  115. ],
  116. 'buyTime'=> intval(oo::commonOprRedis("common")->get(okeys::PropsExpire($uid,"37-buy")))
  117. ];
  118. }else{
  119. $this->decUserProps($uid,$data['id'],$data['count']);
  120. return [];
  121. }
  122. }
  123. return $data;
  124. }
  125. /**
  126. * 获取用户道具信息
  127. * @param $uid
  128. * @param int $id
  129. * @return array|mixed
  130. * Created by: Owen
  131. * Created on: 2020/5/7 18:33
  132. */
  133. public function getUserPropsData($uid,$id = 0){
  134. $cacheKey = okeys::UserProps($uid);
  135. if($id){
  136. $cache = oo::commonOprRedis('common')->hGet($cacheKey,$id);
  137. if(!empty($cache)){
  138. return json_decode($cache,true);
  139. }
  140. $tb = otable::userprops($uid);
  141. $ret = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE uid = {$uid} AND id={$id} LIMIT 1", MYSQLI_ASSOC);
  142. $data = [];
  143. if(!empty($ret)){
  144. oo::commonOprRedis('common')->hSet($cacheKey,$id,json_encode($ret));
  145. $data = $ret;
  146. }
  147. oo::commonOprRedis('common')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
  148. return $data;
  149. }else{
  150. $cache = oo::commonOprRedis('common')->hGetAll($cacheKey);
  151. if(!empty($cache)){
  152. $cacheTemp = [];
  153. foreach ($cache as $row){
  154. $cacheTemp[] = json_decode($row,true);
  155. }
  156. return $cacheTemp;
  157. }
  158. $tb = otable::userprops($uid);
  159. $ret = oo::commonOprDb('common')->getAll("SELECT * FROM {$tb} WHERE uid = {$uid}", MYSQLI_ASSOC);
  160. foreach ($ret as $row){
  161. oo::commonOprRedis('common')->hSet($cacheKey,$row['id'],json_encode($row));
  162. }
  163. oo::commonOprRedis('common')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
  164. return $ret;
  165. }
  166. }
  167. /**
  168. * 保存数据
  169. * @param $uid
  170. * @param $id
  171. * @param $info
  172. * @return bool
  173. * Created by: Owen
  174. * Created on: 2020/5/7 20:03
  175. */
  176. public function updateUserPropsData($uid,$id,$info){
  177. $cacheKey = okeys::UserProps($uid);
  178. $info['isLanding'] = 1;
  179. $ret = oo::commonOprRedis('common')->hSet($cacheKey,$id,json_encode($info));
  180. oo::commonOprRedis('common')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
  181. /** 数据落地标识 */
  182. oo::commonOprRedis('common')->zAdd(okeys::Landing("PROPS", $uid),time(),$uid);
  183. return $ret;
  184. }
  185. /**
  186. * 添加道具
  187. * @param $uid
  188. * @param $id
  189. * @param $count
  190. * @param int $type
  191. * @return array|bool
  192. * Created by: Owen
  193. * Created on: 2019/12/19 19:48
  194. */
  195. public function addUserProps($uid, $id, $count, $type = 0 ,$rid=2001,$ext='') {
  196. if($id == 22){ //钻石发放入口关闭
  197. return true;
  198. }
  199. $propsConfig =$this->getPropsConfig();
  200. if (!$uid || !in_array($id,array_keys($propsConfig))){
  201. return false;
  202. }
  203. $propsInfo = self::getUserPropsData($uid, $id);
  204. $propsData = $propsConfig[$id];
  205. if(empty($propsInfo)){
  206. $tb = otable::userprops($uid);
  207. $now = time();
  208. $query = "INSERT INTO {$tb} (uid,id,`type`,status,`count`,expire,`time`) VALUES ({$uid}, {$id}, {$type}, 0, {$count}, 0, {$now}) ON DUPLICATE KEY UPDATE `type`={$type},`status`=0,`count`={$count},`expire`=0,`time`={$now}";
  209. oo::commonOprDb('common')->query($query);
  210. $cacheKey = okeys::UserProps($uid);
  211. oo::commonOprRedis('common')->hSet($cacheKey,$id,json_encode([
  212. 'uid' =>$uid,
  213. 'id' =>$id,
  214. 'type' =>$type,
  215. 'status'=>0,
  216. 'count' =>$count,
  217. 'expire'=>0,
  218. 'time' =>$now,
  219. ]));
  220. oo::commonOprModel('currency')->log($uid,"props","+",$count,$count,$rid,"{$ext}获得道具:".$propsData['msg']);
  221. }else{
  222. $propsInfo['count'] = $propsInfo['count'] + $count;
  223. self::updateUserPropsData($uid, $id,$propsInfo);
  224. oo::commonOprModel('currency')->log($uid,"props","+",$count,$propsInfo['count'],$rid,"{$ext}获得道具:".$propsData['msg']);
  225. }
  226. return ['code'=>1];
  227. }
  228. /**
  229. * 减少道具数量
  230. * @param $uid
  231. * @param $id
  232. * @param $count
  233. * @return bool|void
  234. * Created by: Owen
  235. * Created on: 2020/5/7 20:03
  236. */
  237. public function decUserProps($uid, $id, $count){
  238. $PropsConfig = $this->getPropsConfig();
  239. if (!$uid || !in_array($id,array_keys($PropsConfig))){
  240. return false;
  241. }
  242. $propsInfo = self::getUserPropsData($uid, $id);
  243. if(empty($propsInfo)){
  244. return false;
  245. }
  246. $propsInfo['count'] = max(0,$propsInfo['count'] - $count);
  247. $propsData = $PropsConfig[$id];
  248. oo::commonOprModel('currency')->log($uid,"props","-",$count,$propsInfo['count'],2002,"使用道具:".$propsData['msg']);
  249. return self::updateUserPropsData($uid, $id,$propsInfo);
  250. }
  251. /**
  252. * 使用用户的道具
  253. * @param $uid
  254. * @param int $id
  255. * @param int $useCount
  256. * @return mixed
  257. * Created by: Owen
  258. * Created on: 2019/12/19 19:55
  259. */
  260. public function useUserProps($uid, $id = 1, $useCount = 1 , $argc = []) {
  261. $propsConfig=$this->getPropsConfig();
  262. if (!$uid || !in_array($id,array_keys($propsConfig))){
  263. return oo::response(-1);
  264. }
  265. $retProps = self::getUserProps($uid, $id);
  266. if(empty($retProps)){
  267. return oo::response(-2);
  268. }
  269. $propsData = $propsConfig[$id];
  270. $data = [];
  271. $myPropsNum = $retProps['count'];
  272. if($id == 8){
  273. $singleNum = $useCount;
  274. $useCount = 1;
  275. }else{
  276. $singleNum = 1;
  277. }
  278. if(0 > $myPropsNum - $singleNum){
  279. return oo::response(-2);
  280. }
  281. self::decUserProps($uid,$id,$singleNum * $useCount);
  282. $version = oo::commonOprModel('user')->getUserVersion($uid);
  283. $versionFlag = oo::compareVersion($version,'1.7.3');
  284. $activityLock = oo::commonOprModel('activitynew')->activityLock($uid,'card');
  285. for ($i=0;$i<$useCount;$i++){
  286. $myPropsNum = $myPropsNum - $singleNum;
  287. if($myPropsNum < 0){
  288. break;
  289. }
  290. if (in_array($propsData['id'],[1,2,3,4])){
  291. $data = oo::commonOprModel('card')->getCardByType($uid,$propsData['id'],0);
  292. oo::commonOprModel('ta')->setEventData($uid,"chest",["chest_id"=>$propsData['id'],"chest_source"=>0,"chest_activity_ratio"=>$activityLock?0.5:0,"chest_reward_card_list"=>array_column($data['card'],"id")]);
  293. break;
  294. }else if($propsData['id'] == 7){
  295. $temp = [];
  296. if($versionFlag){
  297. $data[$i]['index'] = oo::commonOprModel('luckydraw')->action($uid,$temp);
  298. $data[$i]['data'] = $temp;
  299. }else{
  300. $data['rewardIndex'][] = oo::commonOprModel('luckydraw')->action($uid,$temp);
  301. }
  302. }else if($propsData['id'] == 8){
  303. oo::commonOprModel('pet')->addUserPetExp($uid,$argc['petId'],$singleNum,3);
  304. $data['petData'] = oo::commonOprModel('pet')->getUserPet($uid,$argc['petId']);
  305. $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
  306. $data['userData']['star'] = $userAssetsInfo['star'];
  307. }else if($propsData['id'] == 9){
  308. oo::commonOprModel('pet')->feedPet($uid,$argc['petId'],0,3);
  309. $data = oo::commonOprModel('pet')->getUserPet($uid,$argc['petId']);
  310. }else if(in_array($propsData['id'],[19,20,21,29,30])){
  311. $data = self::rewardChest($uid,$propsData['id'],"背包道具",2002,1);
  312. }
  313. }
  314. return oo::response(1,$data,'',true);
  315. }
  316. /**
  317. * 获取宝箱奖励
  318. * @param $uid
  319. * @param $propsId
  320. * @param $reason
  321. * @return bool
  322. * Created by: Owen
  323. * Created on: 2020/9/14 17:30
  324. */
  325. public function rewardChest($uid,$propsId,$reason = "",$rid=2002,$skin = 0){
  326. $config = self::getChestData($uid,$propsId,true,$skin);
  327. if(!$config){
  328. return false;
  329. }
  330. $userCardInfo = oo::commonOprModel('card')->getUserCardInfo($uid);
  331. $userJokerNum = $userCardInfo['jockerNum'];
  332. $data['joker'] = 0;
  333. $version = oo::commonOprModel('user')->getUserVersion($uid);
  334. //1.8.5特殊宝箱添加小丑卡保底值,保底值+配置值>=10000则必出小丑卡
  335. $minGuaranteeNum = empty($userCardInfo['minGuaranteeNum']) ? 0 : (int)$userCardInfo['minGuaranteeNum'];
  336. if(!empty($userCardInfo['jockerNum'])){
  337. $minGuaranteeNum += 250*(int)$userCardInfo['jockerNum'];
  338. }
  339. $calConfNum = $config['jokerCardNum'] <= 0 ? 0 : ceil(10000 / $config['jokerCardNum']);
  340. $anchorNum = $minGuaranteeNum + $calConfNum;
  341. $data['joker'] = 0;
  342. $cardUpdateInfo = [];
  343. if(!oo::commonOprRedis('User')->get(okeys::JokerCard($uid))){
  344. if($config['jokerCardNum'] != 0 && (rand(0,$config['jokerCardNum']) < 1 || $anchorNum >= 10000)) {
  345. $config['cardNum'] = $config['cardNum'] -1;
  346. $cardUpdateInfo['minGuaranteeNum'] = 0; //开出小丑卡,保底值清零
  347. $data['joker'] = oo::commonOprModel('card')->setJokerCard($uid);
  348. oo::commonOprModel('statistics')->jokerCardSta($propsId,1,$uid,'宝箱开出',$rid);//小丑卡统计
  349. }else{
  350. //保底值增加
  351. $cardUpdateInfo['minGuaranteeNum'] = $anchorNum;
  352. }
  353. $cardUpdateInfo['jockerNum'] = 0;
  354. }
  355. if(!empty($cardUpdateInfo)){
  356. oo::commonOprModel('card')->updateUserCardInfo($uid,$cardUpdateInfo);
  357. }
  358. $cardData = oo::commonOprModel('card')->getCardByType($uid,$propsId,$config['cardNum'],[],$skin);
  359. $data['card'] = $cardData['card'];
  360. $spins = $config['spinsNum'][oo::commonOprModel('slot')->get_rand(array_column($config['spinsNum'],"v"))]['num'];
  361. $coins = $config['coinsNum'][oo::commonOprModel('slot')->get_rand(array_column($config['coinsNum'],"v"))]['num'];
  362. oo::commonOprModel('member')->optProperty($uid,['spins'=>$spins,'money'=>$coins],"+",$rid,"特殊宝箱:".$reason);
  363. $petExp = $config['petExp'][oo::commonOprModel('slot')->get_rand(array_column($config['petExp'],"v"))]['num'];
  364. oo::commonOprModel('props')->addUserProps($uid, 8, $petExp,0,$rid);
  365. $food = $config['petFood'];
  366. $food > 0 && oo::commonOprModel('props')->addUserProps($uid, 9, $food,0,$rid);
  367. $coins && $data['props'][] = ['propsId'=>14,'num'=>$coins,'value'=>$coins];
  368. $spins && $data['props'][] = ['propsId'=>15,'num'=>$spins,'value'=>$spins];
  369. $petExp && $data['props'][] = ['propsId'=>8 ,'num'=>$petExp,'value'=>$petExp];
  370. $food && $data['props'][] = ['propsId'=>9 ,'num'=>$food, 'value'=>$food];
  371. $data['propsId'] = $propsId;
  372. $data['skin'] = $skin ? $skin : [19 =>1,20 =>2,21=>3,29=>4,30=>5][$propsId];
  373. oo::commonOprModel('ta')->setEventData($uid,"chest_sp",[
  374. "chest_id"=>$skin,
  375. "chest_source"=>$rid,
  376. "chest_activity_ratio"=>oo::commonOprModel('activitynew')->activityLock($uid,'card') ? 0.5 : 0,
  377. "chest_reward_spin"=>intval($spins),
  378. "chest_reward_coin"=>intval($coins),
  379. "chest_reward_petfood"=>intval($food),
  380. "chest_reward_petexp"=>intval($petExp),
  381. "chest_reward_card_list"=>array_column($data['card'],'id') ,
  382. "chest_reward_card_joker"=>$data['joker'] > 0 ? 1 : 0
  383. ]);
  384. return $data;
  385. }
  386. /**
  387. * 宝箱数据
  388. * @param $id
  389. * @param $reward
  390. * @return mixed
  391. * Created by: Owen
  392. * Created on: 2020/9/14 15:20
  393. */
  394. public function getChestData($uid,$id,$reward = false,$skin = 0){
  395. if(in_array($id,[19,20,21,29,30])){
  396. $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
  397. $conf = $skin ? oo::commonOprModel('config')->getChestSkinConfig($skin) : oo::commonOprModel('config')->getChestConfig($id);
  398. $conf = array_column($conf,NULL,'propsId');
  399. $cardNum = $conf[17]['num'];
  400. $jokerCardNum = $conf[18]['num'];
  401. $coinsNumPro = $this->getChestWeightByLevelId($conf[14]['pro'],$userAssetsInfo['levelId']);
  402. $spinsNumPro = $this->getChestWeightByLevelId($conf[15]['pro'],$userAssetsInfo['levelId']);
  403. $petExpPro = $this->getChestWeightByLevelId($conf[8]['pro'],$userAssetsInfo['levelId']);
  404. $food = intval($conf[9]['num']);
  405. if($reward){
  406. return [
  407. 'cardNum' => $cardNum,
  408. 'jokerCardNum' => $jokerCardNum,
  409. 'coinsNum' => $coinsNumPro,
  410. 'spinsNum' => $spinsNumPro,
  411. 'petExp' => $petExpPro,
  412. 'petFood' => $food,
  413. ];
  414. }else{
  415. $coinsNum = $coinsNumPro ? array_column($coinsNumPro,'num') : [];
  416. $spinsNum = $spinsNumPro ? array_column($spinsNumPro,'num') : [];
  417. $petExp = $petExpPro ? array_column($petExpPro ,'num') : [];
  418. return [
  419. 'skin' => $skin ? $skin : [19 =>1,20 =>2,21=>3,29=>4,30=>5][$id],
  420. 'cardNum' => $cardNum,
  421. 'jokerCardNum' => $jokerCardNum,
  422. 'coinsNum' => !empty($coinsNum) ? [min($coinsNum),max($coinsNum)] : [],
  423. 'spinsNum' => !empty($spinsNum) ? [min($spinsNum),max($spinsNum)] : [],
  424. 'petExp' => !empty($petExp) ? [min($petExp),max($petExp)] : [],
  425. 'petFood' => $food,
  426. ];
  427. }
  428. }
  429. return false;
  430. }
  431. /**
  432. * 根据等级获取配置
  433. * @param $data
  434. * @param $lv
  435. * @return array|mixed
  436. * Created by: Owen
  437. * Created on: 2021/3/3 12:11
  438. */
  439. public function getChestWeightByLevelId($data,$lv){
  440. $lv = max($lv,1);
  441. $ret = [];
  442. foreach ($data as $d){
  443. if($d['lv'] <= $lv){
  444. $ret = $d['weight'];
  445. }else{
  446. break;
  447. }
  448. }
  449. return $ret;
  450. }
  451. public function setFirstPayPromotion($uid){
  452. oo::commonOprModel('props')->addUserProps($uid, 37, 1,0,304);
  453. $curTime = time();
  454. $baseTime = 0;
  455. $config = oo::commonOprModel('activitynew')->activityLock($uid, 'shop_promotion', true);
  456. if(!empty($config)){
  457. $baseTime = max($config['activityData']['end'] - $curTime,0);
  458. }
  459. if(oo::commonOprRedis('common')->get(okeys::UserAbTest($uid)) > 1){
  460. $actionTime = $baseTime + 3 *24 *60 *60;
  461. }else{
  462. $actionTime = $baseTime + 7 *24 *60 *60;
  463. }
  464. oo::commonOprRedis("common")->setex(okeys::PropsExpire($uid,"37-spins"),1,$actionTime);
  465. oo::commonOprRedis("common")->setex(okeys::PropsExpire($uid,"37-coins"),1,$actionTime);
  466. oo::commonOprRedis("common")->setex(okeys::PropsExpire($uid,"37-buy"),$curTime,$actionTime);
  467. return [
  468. 'spins' => [
  469. 'time' => $curTime + $actionTime,
  470. 'buyTimes' => 0,
  471. 'totalTimes' => 1,
  472. ],
  473. 'coins' => [
  474. 'time' => $curTime + $actionTime,
  475. 'buyTimes' => 0,
  476. 'totalTimes' => 1,
  477. ],
  478. 'buyTime' => $curTime
  479. ];
  480. }
  481. }