coindozer.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. <?php
  2. /**
  3. * Notes:推金币小游戏
  4. *
  5. * User: wsc
  6. * Time: 2020/11/18 14:16
  7. * Class ModelCoindozer
  8. */
  9. class ModelCoindozer{
  10. public $gameCfg =[
  11. "freeLimit"=>3,//免费次数
  12. "status"=>1,//状态
  13. "iosSet"=>[//ios设置
  14. "minVersion"=>'1.7.8',//最小开启版本
  15. "status"=>0 //开启状态
  16. ],
  17. "androidSet"=>[//安卓设置
  18. "minVersion"=>'1.7.0',
  19. "status"=>1
  20. ],
  21. "buyGameLimit"=>[
  22. "prize"=>20,//单价
  23. "maxNum"=>100,//最大次数
  24. ],
  25. "commonCfg"=>[ //常规用户
  26. "openLevel"=>8,//开放等级
  27. "freeExpLimit"=>1,//体验次数
  28. "expLevel"=>1, //体验等级
  29. "openExp"=>1, //是否开放渠道体验
  30. ],
  31. "specialCfg"=>[//广告渠道用户
  32. "openLevel"=>3,//开放等级
  33. "freeExpLimit"=>1,//体验次数
  34. "expLevel"=>1,//体验等级
  35. "openExp"=>1,//是否开放渠道体验
  36. ],
  37. "initTableModel"=>1,//初始化桌面的模式
  38. "buyGameProp"=>[//游戏道具价格
  39. "p1"=>["prize"=>20,"maxNum"=>100],
  40. "p2"=>["prize"=>40,"maxNum"=>100],
  41. ],
  42. ];
  43. //等级汇率 +
  44. public $exchangeRateCfg=[
  45. ["level"=>1,"er"=>1],
  46. ["level"=>2,"er"=>2],
  47. ["level"=>3,"er"=>3],
  48. ["level"=>4,"er"=>4],
  49. ["level"=>5,"er"=>5],
  50. ["level"=>6,"er"=>10],
  51. ];
  52. //掉落位置概率
  53. public $siteProbCfg=[
  54. ["id"=>1,"weight"=>10],
  55. ["id"=>2,"weight"=>10],
  56. ["id"=>3,"weight"=>10],
  57. ["id"=>4,"weight"=>9],
  58. ["id"=>5,"weight"=>15],
  59. ["id"=>6,"weight"=>8],
  60. ["id"=>7,"weight"=>15],
  61. ["id"=>8,"weight"=>8],
  62. ["id"=>9,"weight"=>2],
  63. ["id"=>10,"weight"=>8],
  64. ["id"=>11,"weight"=>2],
  65. ["id"=>12,"weight"=>1],
  66. ["id"=>13,"weight"=>2],
  67. ];
  68. //道具掉落规则 +
  69. public $propDropRule=[
  70. ["stage"=>100,"everyNum"=>10,"dropNum"=>1],
  71. ["stage"=>500,"everyNum"=>15,"dropNum"=>1],
  72. ["stage"=>2000,"everyNum"=>20,"dropNum"=>1],
  73. ["stage"=>10000,"everyNum"=>25,"dropNum"=>1],
  74. ["stage"=>100000000,"everyNum"=>30,"dropNum"=>1],
  75. ];
  76. //掉落道具概率 +
  77. public $propProbCfg=[
  78. ["id"=>1,"weight"=>360,"type"=>14,"rtype"=>2,"snum"=>2,"enum"=>10],
  79. ["id"=>2,"weight"=>120,"type"=>14,"rtype"=>2,"snum"=>11,"enum"=>30],
  80. ["id"=>3,"weight"=>40,"type"=>14,"rtype"=>2,"snum"=>31,"enum"=>60],
  81. ["id"=>4,"weight"=>10,"type"=>14,"rtype"=>2,"snum"=>61,"enum"=>100],
  82. ["id"=>5,"weight"=>220,"type"=>15,"rtype"=>2,"snum"=>1,"enum"=>5],
  83. ["id"=>6,"weight"=>110,"type"=>15,"rtype"=>2,"snum"=>6,"enum"=>10],
  84. ["id"=>7,"weight"=>50,"type"=>15,"rtype"=>2,"snum"=>11,"enum"=>20],
  85. ["id"=>8,"weight"=>10,"type"=>15,"rtype"=>2,"snum"=>21,"enum"=>50],
  86. ["id"=>9,"weight"=>80,"type"=>1,"rtype"=>1,"snum"=>1,"enum"=>1],
  87. ];
  88. //关于游戏记录的说明:rid 1消耗次数 2购买次数
  89. /**
  90. * Notes:配置
  91. * User: wsc
  92. * Time: 2020/11/18 14:39
  93. * @return array
  94. */
  95. public function getConfig(){
  96. $config = oo::commonOprModel('readconfig')->getSysCon('CoinDozer',"config");
  97. $config = !empty($config)?json_decode($config,true):[];
  98. if(empty($config)||!is_array($config)){
  99. $config['gameCfg'] = $this->gameCfg;//游戏基本配置
  100. $config['exchangeRateCfg'] = $this->exchangeRateCfg;//汇率规则配置
  101. $config['siteProbCfg'] = $this->siteProbCfg;//位置概率配置
  102. $config['propDropRule'] = $this->propDropRule;//道具掉落规则
  103. $config['propProbCfg'] = $this->propProbCfg;//道具掉落物品生成概率配置
  104. }
  105. return $config;
  106. }
  107. /**
  108. * Notes:获取游戏信息
  109. * User: wsc
  110. * Time: 2020/11/24 15:12
  111. * @param $uid
  112. * @return mixed
  113. */
  114. public function getOpenInfo($uid){
  115. $gameCfg = $this->getConfig()['gameCfg'];
  116. $userInfo= oo::commonOprModel('member')->getUserBasic($uid);
  117. $isClose =false;
  118. if(!isset($gameCfg['androidSet'])) $gameCfg['androidSet']= $this->gameCfg['androidSet'];//未配置时初始化本地设置
  119. if(!isset($gameCfg['iosSet'])) $gameCfg['iosSet']= $this->gameCfg['iosSet'];//未配置时初始化本地设置
  120. $sid = oo::getDefinedSid($uid);
  121. if ($sid==1&&($gameCfg['androidSet']['status']!=1||!oo::compareVersion($userInfo['version'],$gameCfg['androidSet']['minVersion']))) $isClose =true;
  122. if ($sid==2&&($gameCfg['iosSet']['status']!=1||!oo::compareVersion($userInfo['version'],$gameCfg['iosSet']['minVersion']))) $isClose =true;
  123. if ($gameCfg['status']!=1) $isClose =true;
  124. if($isClose){
  125. $data['buyLimitPrize'] = 0;
  126. $data['haveLimit'] = 0;
  127. $data['isOpen']=0;
  128. $data['status']=0;
  129. $data['openLevel'] =999;
  130. return $data;
  131. }
  132. $userGameInfo= $this->getUserGameInfo($uid);
  133. $playLimit = intval($userGameInfo['dayInfo']['playLimit']);
  134. $allLimit = $gameCfg['freeLimit']+$userGameInfo['dayInfo']['buyGameLimit'];
  135. $data['isSpecial'] = $this->specialUser($uid)?1:0;
  136. if($data['isSpecial']){//广告渠道用户
  137. $thisCfg = $gameCfg['specialCfg'];
  138. }else{
  139. $thisCfg = $gameCfg['commonCfg'];
  140. }
  141. $status =1;
  142. if($thisCfg['openExp']==1&&$userInfo['levelId']==$thisCfg['expLevel']){//体验次数
  143. $allLimit = $thisCfg['freeExpLimit'];
  144. if($allLimit<=$playLimit){//次数不够
  145. $status = errorCode::LIMIT_NOT_RNOUGH;
  146. }
  147. }
  148. //当没有开放体验,或者开放体验等级不满足的情况下,等级不够
  149. if(($userInfo['levelId']!=$thisCfg['expLevel']||$thisCfg['openExp']!=1)&&$userInfo['levelId']<$thisCfg['openLevel']){
  150. $status = errorCode::LEVEL_NOT_RNOUGH;
  151. }
  152. $have = $allLimit-$playLimit;
  153. $data['buyLimitPrize'] = $gameCfg['buyGameLimit']['prize'];
  154. $data['haveLimit'] = $have>0?$have:0;
  155. $data['isOpen'] =$status>0?1:0;
  156. $data['status'] =$gameCfg['status'];
  157. $data['openLevel'] = $thisCfg['openLevel'];
  158. return $data;
  159. }
  160. /**
  161. * Notes:获取用户游戏信息
  162. * User: wsc
  163. * Time: 2020/11/18 17:32
  164. * @param $uid
  165. * @return mixed
  166. */
  167. public function getUserGameInfo($uid){
  168. $key1 = okeys::userGameInfoCoinDozer($uid);
  169. $info['info'] = oo::commonOprRedis('usercache')->hGetAll($key1);
  170. if(empty($info['info'])){
  171. $tb = otable::usercoindozer();
  172. $sql = "select * from {$tb} where uid={$uid}";
  173. $datas = oo::commonOprDb('userinfo')->getOne($sql,1);
  174. if(!empty($datas)){
  175. $res = true;
  176. }else{
  177. $datas = ["uid"=>$uid,"level"=>1,"exp"=>0,"p1"=>0,"p2"=>0,"ext"=>"","create_ts"=>time()];
  178. if(funs::concurrentLock($uid,'insert_coindozer')){
  179. $sql = funs::db_insertSQL($tb,$datas);
  180. $res = oo::commonOprDb('userinfo')->query($sql);
  181. }else{
  182. $res =true;
  183. }
  184. }
  185. if($res){
  186. oo::commonOprRedis('usercache')->hMset($key1,$datas);
  187. oo::commonOprRedis('usercache')->expire($key1,oo::redisRandomExpire(86400*7));
  188. }
  189. $info['info'] = $datas;
  190. }
  191. !empty($info['info']['ext'])&&$info['info']['ext'] = json_decode($info['info']['ext'],true);
  192. $info['dayInfo'] = $this->getUserDayGameInfo($uid);
  193. return $info;
  194. }
  195. /**
  196. * Notes:获取当日数据
  197. * User: wsc
  198. * Time: 2020/12/22 16:09
  199. * @param $uid
  200. * @return array
  201. */
  202. public function getUserDayGameInfo($uid){
  203. $key2 = okeys::userDayGameInfoCoinDozer($uid);
  204. $dayInfo = oo::commonOprRedis('usercache')->hGetAll($key2);
  205. if(empty($dayInfo)){
  206. $dayInfo = ["playLimit"=>0,"putLimit"=>0,"buyGameLimit"=>0,"buyP1Limit"=>0,"buyP2Limit"=>0,"useP1Limit"=>0,"useP2Limit"=>0];//初始化次数
  207. oo::commonOprRedis('usercache')->hMset($key2,$dayInfo);
  208. oo::commonOprRedis('usercache')->expire($key2,oo::todayDeadline());//设置过期
  209. }
  210. return $dayInfo;
  211. }
  212. /**
  213. * Notes:设置次数记录
  214. * User: wsc
  215. * Time: 2020/12/22 16:12
  216. * @param $uid
  217. * @param $key string 要设置的类型
  218. * @param $num int 要设置的数量
  219. * @param $type int 日志类型
  220. * @param $rid int 原因id
  221. * @param $limit int 第几次
  222. * @param string $ext
  223. */
  224. public function changeUserDayGameInfo($uid,$key,$num,$type,$rid,$ext=''){
  225. $keys = okeys::userDayGameInfoCoinDozer($uid);
  226. if(!oo::commonOprRedis('usercache')->exists($keys)){//防止缓存空置期异常不过期
  227. $this->getUserDayGameInfo($uid);
  228. }
  229. $limit = oo::commonOprRedis('usercache')->hIncrBy($keys,$key,$num);
  230. if($key!='putLimit'){//不记录当天投放次数
  231. $log = ["uid"=>$uid,"type"=>$type,"rid"=>$rid,"num"=>$num,"limit"=>$limit,"time"=>time(),"ext"=>$ext];//购买次数记录
  232. oo::commonOprRedis('statistics')->rpush(okeys::coinDozerGameLogList(),json_encode($log));
  233. }
  234. return $limit;
  235. }
  236. /**
  237. * Notes:更新用户游戏信息缓存
  238. * User: wsc
  239. * Time: 2020/11/20 18:29
  240. * @param $uid
  241. * @param $data
  242. */
  243. public function upDataGameInfo($uid,$data){
  244. $key1 = okeys::userGameInfoCoinDozer($uid);
  245. foreach ($data as $k=>$v){
  246. oo::commonOprRedis('usercache')->hSet($key1,$k,$v);
  247. }
  248. $key = okeys::Landing("COINDOZER_GAMEDATA");//数据落地标识
  249. oo::commonOprRedis('Usercache')->zAdd($key,time(),$uid);
  250. }
  251. /**
  252. * Notes:购买
  253. * User: wsc
  254. * Time: 2020/11/20 18:00
  255. * @param int $uid 用户id
  256. * @param int $num 购买数量
  257. * @param int $type 0购买游戏次数 1购买道具p1 2购买道具p2
  258. * @return array
  259. */
  260. public function buy($uid,$num=1,$type=0){
  261. $num =abs($num);
  262. $cfgs = $this->getConfig()['gameCfg'];
  263. $userGameInfo = $this->getUserGameInfo($uid);
  264. if($type==1){
  265. $key = "buyP1Limit";
  266. $cfg = $cfgs['buyGameProp']['p1'];
  267. $p = 'p1';
  268. $rid =91;
  269. }else if($type==2){
  270. $key = "buyP2Limit";
  271. $cfg = $cfgs['buyGameProp']['p2'];
  272. $p = 'p2';
  273. $rid =91;
  274. }else{
  275. $key="buyGameLimit";
  276. $rid =90;
  277. $cfg = $cfgs['buyGameLimit'];
  278. }
  279. $buyLimit = intval($userGameInfo['dayInfo'][$key]);//已购买的次数
  280. $userAttr = oo::commonOprModel('member')->getUserAssetsInfo($uid);
  281. $data = $userGameInfo;
  282. $data['userAttr']['money'] = $userAttr['money'];
  283. $data['userAttr']['diamond'] = $userAttr['diamond'];
  284. //道具购买配置
  285. if($buyLimit+$num>$cfg['maxNum']){//单日购买最大次数上限
  286. return ["code"=>errorCode::LIMIT_NOT_RNOUGH,"data"=>$data];
  287. }
  288. if($cfg['prize']*$num>$userAttr['diamond']){//钻石不足
  289. return ["code"=>errorCode::DIAMOND_NOT_ENOUGH,"data"=>$data];
  290. }
  291. $res =oo::commonOprModel('member')->optProperty($uid,["diamond"=>$cfg['prize']*$num],"-",$rid,"购买数:$num:{$key}");
  292. if(!$res){
  293. return ["code"=>errorCode::DIAMOND_NOT_ENOUGH,"data"=>$data];
  294. }
  295. if($type>0){//道具发货
  296. $count = $userGameInfo['info'][$p]+$num;
  297. $this->upDataGameInfo($uid,[$p=>$count]);
  298. $data['info'][$p]=$count;
  299. }else{
  300. $data['dayInfo'][$key] = $userGameInfo['dayInfo'][$key]+$num;
  301. }
  302. //写记录
  303. $this->changeUserDayGameInfo($uid,$key,$num,2,$rid,$key);
  304. $putLimit = $data['dayInfo']['putLimit'];
  305. unset($data['dayInfo'],$data['info']['uid'],$data['info']['create_ts'],$data['info']['ext']);
  306. $data['dayInfo']['putLimit'] = $putLimit;
  307. $data['userAttr']['diamond'] = $userAttr['diamond']-$cfg['prize']*$num;
  308. return ["code"=>errorCode::SUCCESS,"data"=>$data];
  309. }
  310. /**
  311. * Notes:使用游戏道具
  312. * User: wsc
  313. * Time: 2020/11/20 18:29
  314. * @param $uid
  315. * @param $type
  316. */
  317. public function useProp($uid,$type){
  318. $userGameInfo = $this->getUserGameInfo($uid);
  319. $userAttr = oo::commonOprModel('member')->getUserAssetsInfo($uid);
  320. if($type==1){
  321. $key = "useP1Limit";
  322. $p='p1';
  323. }else if($type==2){
  324. $key = "useP2Limit";
  325. $p='p2';
  326. }else{
  327. return ["code"=>errorCode::REQUEST_PARAM_ERROR,"data"=>[]];
  328. }
  329. $pNum = intval($userGameInfo['info'][$p]);
  330. $data = $userGameInfo;
  331. $data['userAttr']['diamond'] = $userAttr['diamond'];
  332. $data['userAttr']['money'] = $userAttr['money'];
  333. $data['type'] = $type;
  334. if($pNum==0){
  335. return ["code"=>errorCode::PROP_NOT_RNOUGH,"data"=>$data];
  336. }
  337. //扣除道具
  338. $num = $pNum-1;
  339. $this->upDataGameInfo($uid,[$p=>$num]);
  340. $data['info'][$p]=$num;
  341. $putLimit = $data['dayInfo']['putLimit'];
  342. unset($data['dayInfo'],$data['info']['uid'],$data['info']['create_ts'],$data['info']['ext']);
  343. $data['dayInfo']['putLimit'] = $putLimit;
  344. //写道具使用记录
  345. $this->changeUserDayGameInfo($uid,$key,1,3,94,$key);
  346. return ["code"=>errorCode::SUCCESS,"data"=>$data];
  347. }
  348. /**
  349. * Notes:开启游戏
  350. * User: wsc
  351. * Time: 2020/11/18 17:23
  352. * @param $uid
  353. * @return array
  354. */
  355. public function openGame($uid,$init=0){
  356. if($init){//重新初始化
  357. oo::commonOprRedis('usercache')->delete(okeys::userDayGameInfoCoinDozer($uid));
  358. oo::commonOprRedis('usercache')->delete(okeys::userCoinDozerPropList($uid));
  359. }
  360. $cfgs = $this->getConfig();
  361. unset($cfgs['propProbCfg']);
  362. $gameCfg = $cfgs['gameCfg'];
  363. $userGameInfo = $this->getUserGameInfo($uid);
  364. $playLimit = intval($userGameInfo['dayInfo']['playLimit']);
  365. $userInfo = oo::commonOprModel('member')->getUserBasic($uid);
  366. $allLimit = $gameCfg['freeLimit']+$userGameInfo['dayInfo']['buyGameLimit'];
  367. $status =1;
  368. $cfgs['exchangeRateCfg'] = $this->getCoinEXRateCfg($cfgs['exchangeRateCfg'],$userInfo['levelId']);
  369. $data['endTime']= timeFuns::today()[1]-30;
  370. $data['status']=0;
  371. $data["userData"] = $userGameInfo;
  372. $putLimit = $data["userData"]['dayInfo']['putLimit'];
  373. unset($data["userData"]['dayInfo'],$data["userData"]['info']['uid'],$data["userData"]['info']['create_ts'],$data["userData"]['info']['ext']);
  374. $data["userData"]['dayInfo']['putLimit'] = $putLimit;
  375. $data["dropPropList"] =[];
  376. $data["gameData"] =[
  377. 'initTableModel'=>0,//初始模式
  378. // 'initTableData'=>[],//初始化桌面
  379. 'config'=>$cfgs,
  380. ];
  381. $isPass = $this->specialUser($uid);//特殊人群(无视等级,不使用有效次数,多免费体验次数)
  382. if($isPass){//广告渠道用户
  383. $thisCfg = $gameCfg['specialCfg'];
  384. }else{
  385. $thisCfg = $gameCfg['commonCfg'];
  386. }
  387. if($thisCfg['openExp']==1&&$userInfo['levelId']==$thisCfg['expLevel']){//体验次数
  388. $allLimit = $thisCfg['freeExpLimit'];
  389. }
  390. //当没有开放体验,或者开放体验等级不满足的情况下,等级不够
  391. if(($userInfo['levelId']!=$thisCfg['expLevel']||$thisCfg['openExp']!=1)&&$userInfo['levelId']<$thisCfg['openLevel']){
  392. $status = errorCode::LEVEL_NOT_RNOUGH;
  393. }
  394. if($allLimit<=$playLimit){//次数不够
  395. $status = errorCode::LIMIT_NOT_RNOUGH;
  396. }
  397. if($gameCfg['status']!=1){//未开启
  398. $status = errorCode::NOT_OPEN;
  399. }
  400. if($status>0){
  401. $props = array_values($this->getDropPropList($uid));
  402. if($playLimit==0){//每天首次玩
  403. $data['gameData']['initTableModel'] = $gameCfg['initTableModel'];
  404. // $data['gameData']['initTableData'] = $this->initTabelData($uid);//初始化桌面数据
  405. }
  406. //写玩次数记录并改变次数
  407. $playLimit = $this->changeUserDayGameInfo($uid,'playLimit',1,1,1,$isPass);
  408. // $data["userData"]['dayInfo']['playLimit'] = $playLimit;
  409. $data["dropPropList"] = $props;
  410. $data['status'] = 1;
  411. }
  412. oo::commonOprModel('currency')->participation($uid, 'coindozer', 0); //推金币参与率统计
  413. return ["code"=>$status,"data"=>$data];
  414. }
  415. /**
  416. * Notes:上报领奖及消耗
  417. * User: wsc
  418. * Time: 2020/11/19 15:27
  419. * @param int $uid
  420. * @param int $putNum 投放的游戏内金币个数
  421. * @param int $dropNum 掉落的游戏内金币个数
  422. * @param string $lostPidsStr 丢失的道具
  423. * @param string $getPidsStr 获取的道具
  424. * @return string
  425. */
  426. public function sub($uid,$putNum,$dropNum,$lostPidsStr="",$getPidsStr=""){
  427. if(intval($putNum)<0){
  428. return oo::response(errorCode::REQUEST_PARAM_ERROR,[],'error args');
  429. }
  430. $userGameInfo = $this->getUserGameInfo($uid);
  431. $userAttr = oo::commonOprModel('member')->getUserAssetsInfo($uid);
  432. $exchangeRateCfg = $this->getConfig()['exchangeRateCfg'];
  433. $exchangeRateCfg = $this->getCoinEXRateCfg($exchangeRateCfg,$userAttr['levelId']);
  434. //汇率计算
  435. $exchangeRateCfg =array_column($exchangeRateCfg,null,'level');
  436. $bet = intval($exchangeRateCfg[$userGameInfo['info']['level']]['er']);//汇率
  437. $lostMoney = $bet*$putNum;
  438. $canGetMoney = $getMoney = $bet*$dropNum;
  439. if(!empty($getPidsStr)){
  440. $getPids = explode(',',$getPidsStr);
  441. foreach ($getPids as $solePid){
  442. $arr = explode('_',$solePid);
  443. if($arr[0]==14){
  444. $canGetMoney +=intval($arr[1])*$bet;
  445. }
  446. }
  447. }
  448. if($userAttr['money']+$canGetMoney<$lostMoney){
  449. $data['userAttr']['money'] = $userAttr['money'];
  450. $data['userAttr']['spins'] = $userAttr['spins'];
  451. $data['userAttr']['coins'] = $userAttr['money'];
  452. $data['userAttr']['diamond'] = $userAttr['diamond'];
  453. oo::logs()->debug3(['time'=>date("Y-m-d H:i:s"),"uid"=>$uid,"putNum"=>$putNum,"dropNum"=>$dropNum,"lostPidsStr"=>$lostPidsStr,"getPidsStr"=>$getPidsStr,"canGetMoney"=>$canGetMoney,"havemoney"=>$userAttr['money']],'coindozer.log');
  454. return oo::response(errorCode::MONEY_NOT_RNOUGH,$data,'be short of gold coins');
  455. }
  456. if($getMoney>0){
  457. oo::commonOprModel('member')->optProperty($uid,["money"=>$getMoney],"+",92);//加钱
  458. }
  459. if($lostMoney>0){
  460. oo::commonOprModel('member')->optProperty($uid,["money"=>$lostMoney],"-",92);//扣钱
  461. }
  462. $proteEndTs = oo::commonOprModel('activitynew')->getEndproteTime($uid);
  463. if($getMoney>0){
  464. $ttl = $proteEndTs-time();
  465. if($ttl < 100){
  466. oo::commonOprModel('member')->setUserStealProtect($uid,300);
  467. $proteEndTs = time()+298;
  468. }
  469. }
  470. if(!empty($lostPidsStr)){//丢失的道具
  471. $lostPids = explode(',',$lostPidsStr);
  472. foreach ($lostPids as $solePid){
  473. oo::commonOprRedis('usercache')->hDel(okeys::userCoinDozerPropList($uid),$solePid);//剔除缓存道具
  474. }
  475. }
  476. $getList = [];
  477. if(!empty($getPids)){//获得的道具
  478. foreach ($getPids as $solePid){
  479. $propStr = oo::commonOprRedis('usercache')->hGet(okeys::userCoinDozerPropList($uid),$solePid);
  480. if($propStr){
  481. $prop = json_decode($propStr,true);
  482. if($prop['type']==14){
  483. $prop['num'] = $prop['num']*$bet;
  484. }
  485. oo::commonOprModel('member')->sendReward($uid,$prop['type'],$prop['num'],93,'');//发放道具
  486. oo::commonOprRedis('usercache')->hDel(okeys::userCoinDozerPropList($uid),$solePid);//剔除缓存道具
  487. $getList[] = $solePid;//得到的道具id
  488. }
  489. }
  490. }
  491. $data = $userGameInfo;
  492. unset($data['dayInfo'],$data['info']['uid'],$data['info']['create_ts'],$data['info']['ext']);
  493. $limit = $this->changeUserDayGameInfo($uid,'putLimit',$putNum,1,1);//累计投放次数
  494. $data['dayInfo']['putLimit'] = $limit;
  495. $userAttr = oo::commonOprModel('member')->getUserAssetsInfo($uid);
  496. $data['userAttr']['money'] = $userAttr['money'];
  497. $data['userAttr']['diamond'] = $userAttr['diamond'];
  498. $data['userAttr']['spins'] = $userAttr['spins'];
  499. $data['getData'] = $getList;
  500. $data['proteEndTs'] = $proteEndTs;
  501. return oo::response(1,$data,'success');
  502. }
  503. public function getCoinEXRateCfg($cfg,$levelId){
  504. foreach ($cfg as $k=> $v){
  505. if($v['er']>100){//兼容线上(防止版本更新时间差导致的异常)
  506. $v['er'] =1;
  507. }
  508. $cfg[$k]['er'] = oo::commonOprModel('activitynew')->getCoinRewardByTypeAndLevel('coin_dozer',$levelId)*$v['er'];
  509. }
  510. return $cfg;
  511. }
  512. /**
  513. * Notes:获取道具列表
  514. * User: wsc
  515. * Time: 2020/11/19 14:13
  516. * @param $uid
  517. * @param string $pids
  518. * @return array
  519. */
  520. public function getDropPropList($uid,$type=0,$pids=''){
  521. $key = okeys::userCoinDozerPropList($uid);
  522. if($pids){
  523. oo::commonOprRedis('usercache')->delete($key);
  524. }
  525. $jsonArr = oo::commonOprRedis('usercache')->hGetAll($key);
  526. $props =funs::getArrFromJsonArr($jsonArr);
  527. $haveCount = !empty($props)?intval(count($props)):0;
  528. if($haveCount<20){
  529. $newProps = $this->getRandProp($uid,50-$haveCount,$pids);
  530. if($type){
  531. return $newProps;
  532. }
  533. $props = array_merge($props,$newProps);
  534. }
  535. return $props;
  536. }
  537. /**
  538. * Notes:获取随机道具
  539. * User: wsc
  540. * Time: 2020/11/18 20:36
  541. * @param int $num 随机个数
  542. * @param int $pid 指定道具
  543. * @return array
  544. */
  545. public function getRandProp($uid,$num=1,$pids=0){
  546. $datas = [];
  547. $cfg = $this->getConfig()['propProbCfg'];
  548. $fplist = $this->filtrationProp($uid);
  549. if(!empty($fplist)){//过滤道具
  550. foreach ($cfg as $k=>$v){
  551. if(in_array($v['type'],$fplist)){
  552. unset($cfg[$k]);
  553. }
  554. }
  555. }
  556. $cfg = array_column($cfg,null,'id');
  557. if($pids){//指定道具
  558. $ids =[$pids];
  559. }else{//随机概率道具
  560. foreach ($cfg as $v){
  561. $idList[$v['id']]=$v['weight'];
  562. }
  563. for ($i=$num;$i--;){
  564. $ids[] = funs::get_randByProb($idList);
  565. }
  566. }
  567. $key = okeys::userCoinDozerPropList($uid);
  568. foreach ($ids as $k=>$id){
  569. $data = [];
  570. $prop = $cfg[$id];
  571. $data['type'] = $prop['type'];
  572. if($prop['rtype']==1){
  573. $data['num'] = $prop['snum'];
  574. }else{
  575. $data['num'] = mt_rand($prop['snum'],$prop['enum']);
  576. }
  577. $data['solePid'] = $prop['type'].'_'.$data['num'].'_'.oo::getMsectime().'_'.$k;
  578. $datas[] = $data;
  579. oo::commonOprRedis('usercache')->hSet($key,$data['solePid'],json_encode($data));//缓存掉落道具,用于验证道具
  580. }
  581. oo::commonOprRedis('usercache')->expire($key,oo::todayDeadline());
  582. return $datas;
  583. }
  584. /**
  585. * Notes:获取初始化桌面数据
  586. * User: wsc
  587. * Time: 2020/11/19 15:35
  588. * @param $uid
  589. * @return array
  590. */
  591. public function initTabelData($uid){
  592. $n =mt_rand(1,3);
  593. $data = [
  594. "coins"=>35+$n,
  595. "props"=>$this->getRandProp($uid,$n),
  596. ];
  597. return $data;
  598. }
  599. /**
  600. * Notes:特殊人群判别
  601. * User: wsc
  602. * Time: 2020/11/19 15:39
  603. * @param $uid
  604. * @return bool
  605. */
  606. public function specialUser($uid){
  607. $ret = oo::commonOprModel('member')->isPushCoinsUser($uid);
  608. return $ret;
  609. }
  610. /**
  611. * Notes:过滤道具
  612. * User: wsc
  613. * Time: 2020/11/19 15:07
  614. * @param $uid
  615. * @return array
  616. */
  617. public function filtrationProp($uid){
  618. $arr = [];
  619. $lv = oo::commonOprModel('member')->getUserLevelId($uid);
  620. if($lv<4){//低等级过滤卡片宝箱,宠物粮食
  621. $arr = [1,2,3,4,9];
  622. }
  623. return $arr;
  624. }
  625. /**
  626. * Notes:定时落地游戏数据
  627. * User: wsc
  628. * Time: 2020/11/26 15:38
  629. * @return mixed
  630. */
  631. public function cronToLandGameLog($sta=false){
  632. $key = okeys::coinDozerGameLogList();
  633. $tb = otable::gamelog_coindozer();
  634. $list = oo::commonOprRedis('statistics')->lGetRange($key,0,999);
  635. $count = count($list);
  636. //按月分表
  637. $td = date('Ym');
  638. $tbs = "gamelog_coindozer_{$td}";
  639. $query = "SHOW TABLES LIKE '$tbs'";
  640. $tbInfo = oo::commonOprDb('log')->getOne($query,1);
  641. if(empty($tbInfo)){
  642. $sql = oo::cfg('sql')['gamelog_coindozer'];
  643. $sql = str_replace('#table#', "gamelog_coindozer_{$td}", $sql);
  644. $res1 =oo::commonOprDb('log')->query($sql);
  645. }else{
  646. $res1 =true;
  647. }
  648. $tb = $res1?$tbs:$tb;
  649. if($list){
  650. foreach ($list as $k=>$v){
  651. $one = json_decode($v,true);
  652. $value = "(";
  653. foreach ($one as $val){
  654. $value .="'{$val}',";
  655. }
  656. $value = trim($value,',');
  657. $value .=")";
  658. $values[] = $value;
  659. }
  660. $fieldArr = ["uid","type","rid","num","limit","time","ext"];
  661. $keys = array_values($fieldArr);
  662. $fields = '(`'.implode('`, `',$keys).'`)';
  663. $values = trim(implode(',',$values),',');
  664. $sql= "INSERT INTO {$tb} {$fields} VALUE {$values}";
  665. $res = oo::commonOprDb('log')->query($sql);
  666. if($res){
  667. oo::commonOprRedis('statistics')->lTrim($key,$count,-1);
  668. }
  669. }
  670. //统计入表
  671. $time = date('Gi', time());
  672. if($time=='006'||$sta){
  673. $ts1 =timeFuns::yesterday()[0];
  674. $ts2 =timeFuns::yesterday()[1];
  675. $tb2 = 'gamelog_coindozer_'.date('Ym',strtotime('-1 days'));
  676. $query = "SHOW TABLES LIKE '$tb2'";
  677. $tbInfo = oo::commonOprDb('log')->getOne($query,1);
  678. if(!$tbInfo){
  679. $tb2 = 'gamelog_coindozer';
  680. }
  681. //人次
  682. $sqls['open_user'] = "SELECT count(a.uid) as num FROM (SELECT uid,count(uid) FROM {$tb2} WHERE type=1 and rid=1 and time>={$ts1} and time<={$ts2} GROUP BY uid) as a";
  683. $sqls['open_num'] = "SELECT count(*) as num FROM {$tb2} WHERE type=1 and rid=1 and time>={$ts1} and time<={$ts2}";
  684. $sqls['buy_game_num'] = "SELECT count(*) as num FROM {$tb2} WHERE type=2 and ext='buyGameLimit' and time>={$ts1} and time<={$ts2}";
  685. $sqls['buy_p1_num'] = "SELECT count(*) as num FROM {$tb2} WHERE type=2 and ext='buyP1Limit' and time>={$ts1} and time<={$ts2}";
  686. $sqls['buy_p2_num'] = "SELECT count(*) as num FROM {$tb2} WHERE type=2 and ext='buyP2Limit' and time>={$ts1} and time<={$ts2}";
  687. foreach ($sqls as $k=> $sq){
  688. $insertData[$k] = intval(oo::commonOprDb('log')->getOne($sq,1)['num']);
  689. }
  690. $insertData['date'] = date('Ymd',$ts1);
  691. $staTb = otable::coinDozerGameSta();
  692. $sql2 = funs::db_insertSQL($staTb,$insertData);
  693. oo::commonOprDb('statistics')->query($sql2);
  694. }
  695. return $res;
  696. }
  697. }