games.action.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Fanwe 方维p2p借贷系统
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2011 http://www.fanwe.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Author: 云淡风轻(1956838968@qq.com)
  8. // +----------------------------------------------------------------------
  9. class gamesModule extends baseModule
  10. {
  11. /**
  12. * redis对象实例
  13. * @var [type]
  14. */
  15. protected static $redis, $video_redis;
  16. /**
  17. * 构造函数,实例化redis对象,导入模型库
  18. */
  19. public function __construct()
  20. {
  21. parent::__construct();
  22. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/GamesRedisService.php');
  23. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/VideoRedisService.php');
  24. self::$redis = new GamesRedisService();
  25. self::$video_redis = new VideoRedisService();
  26. fanwe_require(APP_ROOT_PATH . 'mapi/lib/core/Model.class.php');
  27. Model::$lib = dirname(__FILE__);
  28. }
  29. public function __destruct()
  30. {
  31. parent::__destruct();
  32. }
  33. /**
  34. * api返回信息
  35. * @param string $error 错误信息
  36. * @param integer $status 错误状态
  37. * @param array $data 返回数据
  38. * @return void
  39. */
  40. protected static function returnError($error = '出错了!', $status = 0, $data = [])
  41. {
  42. $data['status'] = $status;
  43. $data['error'] = $error;
  44. if ($error == '参数错误') {
  45. $data['data'] = $_REQUEST;
  46. }
  47. api_ajax_return($data);
  48. }
  49. /**
  50. * 日志写入
  51. * @param object $data 日志数据
  52. * @return void
  53. */
  54. protected static function pushLog($data)
  55. {
  56. if (IS_DEBUG) {
  57. fanwe_require(APP_ROOT_PATH . 'mapi/lib/tools/PushLog.class.php');
  58. PushLog::log($data);
  59. }
  60. }
  61. /**
  62. * 获取用户id
  63. * @return integer 登录用户id
  64. */
  65. protected static function getUserId()
  66. {
  67. $user_id = intval($GLOBALS['user_info']['id']);
  68. if ($_REQUEST['test'] == 'test' && IS_DEBUG) {
  69. return 167277;
  70. }
  71. if (!$user_id) {
  72. self::returnError('未登录');
  73. }
  74. return $user_id;
  75. }
  76. /**
  77. * 获取游戏配置
  78. * @param integer $id 游戏(种类)id
  79. * @param string $field 数据字段
  80. * @return array 游戏(种类)数据
  81. */
  82. protected static function getGameById($id, $field = '')
  83. {
  84. $game = Model::build('games')->field($field)->selectOne(['id' => $id]);
  85. if (!$game) {
  86. self::returnError('游戏参数错误');
  87. }
  88. return $game;
  89. }
  90. /**
  91. * 根据主播id获取直播间id以及group_id
  92. * @param integer $user_id 主播用户id
  93. * @return array [$video_id,$group_id]
  94. */
  95. protected static function getLiveVideoByUserId($user_id)
  96. {
  97. $video = Model::build('video')->getLiveVideoByUserId($user_id, 'id,group_id');
  98. $video_id = intval($video['id']);
  99. if (!($video['id'] && $video['group_id'])) {
  100. self::returnError('不在直播状态');
  101. }
  102. return [$video_id, $video['group_id']];
  103. }
  104. /**
  105. * 获取游戏状态信息
  106. * @param integer $video_id 直播间id
  107. * @return array [$last_game, $last_log_id, $banker_status, $banker_id]
  108. */
  109. protected static function getLastGameByVideoId($video_id)
  110. {
  111. $model = Model::build('games');
  112. return $model::getLastGameByVideoId($video_id);
  113. }
  114. /**
  115. * 获取上庄信息
  116. * @param integer $video_id 直播间id
  117. * @param array $option 下注选项倍数数据
  118. * @return array [$banker_status, $banker_id, $banker_log_id, $banker_name, $banker_img, $coin, $max_bet]
  119. */
  120. protected static function getBankerStatus($video_id, $option)
  121. {
  122. $model = Model::build('games');
  123. return $model::getBankerStatus($video_id, $option);
  124. }
  125. /**
  126. * 游戏参数转换为字符串(参数类型转换)
  127. * @param array $option 下注选项倍数数据
  128. * @return array 下注选项倍数数据
  129. */
  130. protected static function parseOption($option)
  131. {
  132. $model = Model::build('games');
  133. return $model::parseOption($option);
  134. }
  135. /**
  136. * 下庄状态变化,金额返还
  137. * @param integer $video_id 直播间id
  138. * @param string $group_id IM群组id
  139. * @return [type] [description]
  140. */
  141. protected static function stopRedisBanker($video_id, $group_id)
  142. {
  143. $model = Model::build('games');
  144. self::pushLog($model::stopRedisBanker($video_id, $group_id));
  145. }
  146. /**
  147. * 发牌
  148. * @return [type] [description]
  149. */
  150. public function start()
  151. {
  152. $user_id = self::getUserId();
  153. $game_id = intval($_REQUEST['id']);
  154. list(
  155. $video_id,
  156. $group_id
  157. ) = self::getLiveVideoByUserId($user_id);
  158. $game_log_id = Model::build('games')->startGame($game_id, $video_id, $group_id, $user_id);
  159. if (is_string($game_log_id)) {
  160. self::returnError($game_log_id);
  161. }
  162. self::returnError('', 1, compact('game_log_id'));
  163. }
  164. /**
  165. * 下注
  166. * @return [type] [description]
  167. */
  168. public function bet()
  169. {
  170. $user_id = self::getUserId();
  171. $id = intval($_REQUEST['id']);
  172. $bet = intval($_REQUEST['bet']);
  173. $money = intval($_REQUEST['money']);
  174. $key = [1 => 'option1', 2 => 'option2', 3 => 'option3'];
  175. if (!isset($key[$bet])) {
  176. self::returnError('参数错误');
  177. }
  178. $field = 'status,group_id,podcast_id,create_time,long_time,game_id,video_id,option';
  179. $game = self::$redis->get($id, $field);
  180. $option = json_decode($game['option'], 1);
  181. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/UserRedisService.php');
  182. $user_redis = new UserRedisService();
  183. $account_diamonds = $coin = $user_redis->getOne_db(intval($user_id), 'coin');
  184. if (defined('OPEN_DIAMOND_GAME_MODULE') && OPEN_DIAMOND_GAME_MODULE == 1) {
  185. $account_diamonds = $user_redis->getOne_db(intval($user_id), 'diamonds');
  186. }
  187. $return = [
  188. 'account_diamonds' => intval($account_diamonds),
  189. 'coin' => intval($coin),
  190. ];
  191. if (!$game['status']) {
  192. self::returnError('游戏不存在', 0, $return);
  193. }
  194. if (intval($game['create_time'] + $game['long_time'] - NOW_TIME) <= 0) {
  195. self::returnError('超出投注时间', 0, $return);
  196. }
  197. $video = self::$video_redis->getRow_db($game['video_id'], ['banker_id', 'banker_status', 'coin']);
  198. if ($video['banker_status'] == 2) {
  199. if ($video['banker_id'] == $user_id) {
  200. self::returnError('庄家不能投注', 0, $return);
  201. }
  202. $op_bet = self::$redis->getBet($id, [$bet]);
  203. if ($video['coin'] / ($option[$bet] - 1) < $money + $op_bet[0]) {
  204. self::returnError('超出庄家底金最大投注金额', 0, $return);
  205. }
  206. }
  207. $user_model = Model::build('user');
  208. $res = $user_model->coin($user_id, -$money);
  209. if (!$res) {
  210. self::returnError('余额不足', 0, $return);
  211. }
  212. $account_diamonds = $user_model->coin($user_id);
  213. Model::build('coin_log')->addLog($user_id, $id, -$money, $account_diamonds, '游戏投注');
  214. Model::build('user_game_log')->addLog($id, $game['podcast_id'], $money, $user_id, $bet, 1);
  215. self::$redis->bet($id, $bet, $money, $user_id);
  216. list($bet, $user_bet) = self::$redis->getBet($id, [1, 2, 3], $user_id);
  217. $time = intval($game['create_time'] + $game['long_time'] - NOW_TIME);
  218. $time = $time > 0 ? $time : 0;
  219. // 新推送
  220. $ext = [
  221. 'type' => 39,
  222. 'room_id' => intval($game['video_id']),
  223. 'desc' => '',
  224. 'time' => $time,
  225. 'game_id' => intval($game['game_id']),
  226. 'game_log_id' => $id,
  227. 'game_status' => intval($game['status']),
  228. 'game_action' => 2,
  229. 'game_data' => ['bet' => $bet],
  230. ];
  231. $res = timSystemNotify($game['group_id'], $ext);
  232. self::pushLog(compact('res', 'ext', 'data'));
  233. if (defined('OPEN_DIAMOND_GAME_MODULE') && OPEN_DIAMOND_GAME_MODULE == 1) {
  234. $account_diamonds = $user_redis->getOne_db(intval($user_id), 'diamonds');
  235. }
  236. $coin = $user_redis->getOne_db(intval($user_id), 'coin');
  237. self::returnError('', 1, ['data' => [
  238. 'game_status' => intval($game['status']),
  239. 'time' => $time,
  240. 'account_diamonds' => $account_diamonds,
  241. 'coin' => $coin,
  242. 'game_data' => compact('bet', 'user_bet'),
  243. ]]);
  244. }
  245. /**
  246. * 进入直播间获取游戏信息
  247. * @return [type] [description]
  248. */
  249. public function get_video()
  250. {
  251. $id = intval($_REQUEST['id']);
  252. $video_id = intval($_REQUEST['video_id']);
  253. $user_id = self::getUserId();
  254. if (!$id && !$video_id) {
  255. self::returnError('参数错误');
  256. }
  257. if (!$id && $video_id) {
  258. $id = intval(self::$video_redis->getOne_db($video_id, 'game_log_id'));
  259. }
  260. if (!$id) {
  261. self::returnError('');
  262. }
  263. $field = ['video_id', 'group_id', 'status', 'game_id', 'create_time', 'long_time', 'option', 'bet_option', 'dices', 'win'];
  264. for ($i = 1; $i <= 3; $i++) {
  265. $field[] = 'option' . $i;
  266. $field[] = 'option' . $i . ':' . $user_id;
  267. $field[] = 'option_win' . $i;
  268. $field[] = 'option_cards' . $i;
  269. $field[] = 'option_type' . $i;
  270. }
  271. $data = self::$redis->get($id, $field);
  272. $video_id = intval($data['video_id']);
  273. $option = self::parseOption(json_decode($data['option'], 1));
  274. if ($data['game_id'] === false) {
  275. self::returnError('游戏不存在');
  276. }
  277. list($banker_status, $banker_id, $banker_log_id, $banker_name, $banker_img, $coin, $max_bet) = self::getBankerStatus($video_id, $option);
  278. $video = self::$video_redis->getRow_db($video_id, ['principal', 'auto_start']);
  279. $principal = intval($video['principal']);
  280. $auto_start = intval($video['auto_start']);
  281. $public_cards = json_decode($data['public_cards'], 1);
  282. $public_cards = $public_cards ? $public_cards : [];
  283. $dices = json_decode($data['dices'], 1);
  284. $dices = $dices ? $dices : [];
  285. $win = intval($data['win']);
  286. $bet = [];
  287. $user_bet = [];
  288. $cards_data = [];
  289. for ($i = 1; $i <= 3; $i++) {
  290. $bet[] = intval($data['option' . $i]);
  291. $user_bet[] = intval($data['option' . $i . ':' . $user_id]);
  292. $cards = json_decode($data['option_cards' . $i], 1);
  293. $type = intval($data['option_type' . $i]);
  294. $cards_data[] = [
  295. 'cards' => $cards ? $cards : [],
  296. 'type' => $type ? $type : 0,
  297. ];
  298. }
  299. $time = intval($data['create_time'] + $data['long_time'] - NOW_TIME);
  300. $ext = [
  301. 'type' => 39,
  302. 'user_id' => $user_id,
  303. 'desc' => '',
  304. 'room_id' => $data['video_id'],
  305. 'time' => $time > 0 ? $time : 0,
  306. 'game_id' => $data['game_id'],
  307. 'game_log_id' => $id,
  308. 'game_status' => $data['status'],
  309. 'game_action' => 6,
  310. 'auto_start' => $auto_start,
  311. 'option' => array_values($option),
  312. 'bet_option' => json_decode($data['bet_option'], 1),
  313. 'game_data' => compact('public_cards', 'win', 'bet', 'user_bet', 'cards_data', 'dices'),
  314. 'banker_status' => $banker_status,
  315. 'banker' => compact('banker_status', 'banker_id', 'banker_log_id', 'banker_name', 'banker_img', 'coin', 'max_bet'),
  316. 'principal' => $principal,
  317. ];
  318. $res = timSystemNotify($data['group_id'], $ext, [$user_id]);
  319. self::pushLog(compact('res', 'ext'));
  320. self::returnError('', 1, ['data' => $ext, 'game_id' => $data['game_id']]);
  321. }
  322. /**
  323. * 获取游戏记录
  324. * @return [type] [description]
  325. */
  326. public function log()
  327. {
  328. $podcast_id = intval($_REQUEST['podcast_id']);
  329. $game_id = intval($_REQUEST['game_id']);
  330. if (!$podcast_id || !$game_id) {
  331. self::returnError('参数错误');
  332. }
  333. $number = intval($_REQUEST['number']);
  334. $where = [
  335. 'podcast_id' => $podcast_id,
  336. 'game_id' => $game_id,
  337. 'status' => 2,
  338. 'result' => ['>', 0],
  339. ];
  340. $data = Model::build('game_log')->getList('result', $where, 'id desc', $number ? $number : 20);
  341. $res = [];
  342. foreach ($data as $value) {
  343. if ($value['result']) {
  344. $res[] = intval($value['result']);
  345. }
  346. }
  347. self::returnError('', 1, ['data' => $res]);
  348. }
  349. /**
  350. * 停止游戏
  351. * @return [type] [description]
  352. */
  353. public function stop()
  354. {
  355. $user_id = self::getUserId();
  356. list(
  357. $video_id,
  358. $group_id
  359. ) = self::getLiveVideoByUserId($user_id);
  360. list(
  361. $last_game,
  362. $last_log_id,
  363. $banker_status,
  364. $banker_id
  365. ) = self::getLastGameByVideoId($video_id);
  366. if ($banker_status) {
  367. self::stopRedisBanker($video_id, $group_id);
  368. }
  369. if (!$last_log_id) {
  370. self::returnError('不在游戏状态');
  371. }
  372. if (self::$redis->isVideoLock($video_id)) {
  373. self::returnError('操作频率太高了,请等下再点!');
  374. }
  375. self::$redis->lockVideo($video_id);
  376. if ($last_game) {
  377. $res = Model::build('game_log')->stop($last_log_id);
  378. if (!$res) {
  379. self::$redis->unLockVideo($video_id);
  380. self::returnError('服务器繁忙');
  381. }
  382. }
  383. self::$redis->set($last_log_id, array('long_time' => 0));
  384. self::$video_redis->update_db($video_id, array('game_log_id' => 0, 'auto_start' => 0));
  385. if (!$last_game) {
  386. $ext = array(
  387. 'type' => 34,
  388. 'desc' => '',
  389. );
  390. $res = timSystemNotify($group_id, $ext);
  391. }
  392. self::$redis->unLockVideo($video_id);
  393. self::returnError('正在关闭游戏', 1);
  394. }
  395. /**
  396. * 更新用户金币并返回赚取金额
  397. * @return [type] [description]
  398. */
  399. public function userDiamonds()
  400. {
  401. $game_log_id = intval($_REQUEST['id']);
  402. $user_id = self::getUserId();
  403. $gain = 0;
  404. if ($game_log_id) {
  405. $where = [
  406. 'game_log_id' => $game_log_id,
  407. 'user_id' => $user_id,
  408. 'bet' => 0,
  409. 'type' => 2,
  410. ];
  411. $game = self::$redis->get($game_log_id, ['video_id', 'group_id', 'podcast_id']);
  412. if ($game['podcast_id'] == $user_id && OPEN_DIAMOND_GAME_MODULE) {
  413. $gain = 0;
  414. } else {
  415. $log = Model::build('user_game_log')->field('money')->selectOne($where);
  416. $where = [
  417. 'game_log_id' => $game_log_id,
  418. 'user_id' => $user_id,
  419. 'type' => 1,
  420. ];
  421. $gain = $log ? intval($log['money']) : 0;
  422. if (defined('GAME_WINNER') && GAME_WINNER) {
  423. $gain -= Model::build('user_game_log')->sum('money', $where);
  424. }
  425. }
  426. $where = [
  427. 'l.game_log_id' => $game_log_id,
  428. 'l.user_id' => ['u.id'],
  429. 'l.podcast_id' => ['<>', 'l.user_id', 'and', 1],
  430. 'l.bet' => 0,
  431. 'l.type' => 2,
  432. ];
  433. if (defined('GAME_WINNER') && GAME_WINNER) {
  434. $winner = Model::build('user_game_log')->table('user_game_log l,user u')->field('u.nick_name,l.money')->order('l.money desc')->selectOne($where);
  435. if (!$winner) {
  436. unset($winner);
  437. }
  438. }
  439. if ($gain) {
  440. $m_config = load_auto_cache("m_config");
  441. $game_gain_for_alert = intval($m_config['game_gain_for_alert']);
  442. $gain_gift = intval(defined('GAME_REWARD') && GAME_REWARD == 1);
  443. if ($game_gain_for_alert || $gain_gift) {
  444. if ($game['podcast_id'] != $user_id) {
  445. if ($game_gain_for_alert && $gain >= $game_gain_for_alert && !isset($_SESSION['game_gain_for_alert'][md5("$user_id:$game_log_id")])) {
  446. $_SESSION['game_gain_for_alert'][md5("$user_id:$game_log_id")] = 1;
  447. $video_id = intval($game['video_id']);
  448. $group_id = $game['group_id'];
  449. $podcast_id = intval($game['podcast_id']);
  450. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/UserRedisService.php');
  451. $user_redis = new UserRedisService();
  452. $user_info = $user_redis->getRow_db($user_id, array('nick_name'));
  453. $nick_name = $user_info['nick_name'];
  454. self::popMessage($video_id, $group_id, $podcast_id, $podcast_id, "恭喜{$nick_name}赢得{$gain}");
  455. }
  456. if ($gain_gift && !isset($_SESSION['gain_gift'][md5("$user_id:$game_log_id")])) {
  457. $where = ['diamonds' => ['<=', $gain]];
  458. $gift_list = Model::build('prop')->getList($where);
  459. if (empty($gift_list)) {
  460. unset($gift_list);
  461. }
  462. }
  463. }
  464. }
  465. }
  466. }
  467. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/UserRedisService.php');
  468. $user_redis = new UserRedisService();
  469. $user_diamonds = $coin = intval($user_redis->getOne_db($user_id, 'coin'));
  470. if ((defined('OPEN_DIAMOND_GAME_MODULE') && OPEN_DIAMOND_GAME_MODULE == 1) || (defined('OPEN_SEND_DIAMONDS_MODULE') && OPEN_SEND_DIAMONDS_MODULE == 1)) {
  471. $user_diamonds = intval($user_redis->getOne_db($user_id, 'diamonds'));
  472. }
  473. self::returnError('', 1, compact('user_diamonds', 'coin', 'gain', 'gift_list', 'winner'));
  474. }
  475. /**
  476. * 获取兑换比例
  477. * @return [type] [description]
  478. */
  479. public function exchangeRate()
  480. {
  481. $m_config = load_auto_cache("m_config");
  482. $rate = $m_config['coin_exchange_rate'] ? floatval($m_config['coin_exchange_rate']) : 1;
  483. self::returnError('', 1, ['exchange_rate' => $rate]);
  484. }
  485. /**
  486. * 钻石兑换游戏币
  487. * @return [type] [description]
  488. */
  489. public function exchangeCoin()
  490. {
  491. $user_id = self::getUserId();
  492. $diamonds = intval($_REQUEST['diamonds']);
  493. if ($diamonds < 1) {
  494. self::returnError('请输入兑换钻石');
  495. }
  496. Connect::beginTransaction();
  497. //减少用户钻石
  498. $sql = "update " . DB_PREFIX . "user set diamonds = diamonds - " . $diamonds . " where id = '" . $user_id . "' and diamonds >= " . $diamonds;
  499. $GLOBALS['db']->query($sql);
  500. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/UserRedisService.php');
  501. $user_redis = new UserRedisService();
  502. if ($GLOBALS['db']->affected_rows()) {
  503. $user_redis->inc_field($user_id, 'diamonds', -$diamonds);
  504. $account_diamonds = $user_redis->getOne_db(intval($user_id), 'diamonds');
  505. //会员账户 钻石变更日志表
  506. $log_model = Model::build('user_log');
  507. $log_data = [
  508. 'log_time' => NOW_TIME,
  509. 'log_admin_id' => 0,
  510. 'money' => 0,
  511. 'type' => 7,
  512. 'prop_id' => 0,
  513. 'score' => 0,
  514. 'point' => 0,
  515. 'podcast_id' => 0,
  516. 'diamonds' => -$diamonds,
  517. 'video_id' => 0,
  518. 'log_info' => '兑换游戏币',
  519. 'user_id' => $user_id,
  520. 'ticket' => 0,
  521. ];
  522. $log_model->insert($log_data);
  523. $user_model = Model::build('user');
  524. $m_config = load_auto_cache("m_config");
  525. $rate = $m_config['coin_exchange_rate'] ? floatval($m_config['coin_exchange_rate']) : 1;
  526. $res = $user_model->coin($user_id, $diamonds * $rate);
  527. if (!$res) {
  528. Connect::rollback();
  529. self::returnError('兑换失败');
  530. }
  531. $coin = $user_model->coin($user_id);
  532. Model::build('coin_log')->addLog($user_id, -1, $diamonds * $rate, $coin, '钻石兑换游戏币');
  533. Connect::commit();
  534. self::returnError('兑换成功', 1, compact('account_diamonds', 'coin'));
  535. }
  536. Connect::rollback();
  537. self::returnError('余额不足');
  538. }
  539. /**
  540. * 赠送游戏币
  541. * @return [type] [description]
  542. */
  543. public function sendCoin()
  544. {
  545. $user_id = self::getUserId();
  546. $is_nospeaking = Model::build('user')->field('is_nospeaking')->selectOne(['id' => $user_id]);
  547. $is_nospeaking = intval($is_nospeaking['is_nospeaking']);
  548. if ($is_nospeaking) {
  549. self::returnError('被im全局禁言,不能赠送游戏币');
  550. }
  551. $coin = intval($_REQUEST['coin']);
  552. $to_user_id = intval($_REQUEST['to_user_id']);
  553. if (!($user_id && $to_user_id && $coin > 0)) {
  554. self::returnError('请输入游戏币');
  555. }
  556. $user_model = Model::build('user');
  557. Connect::beginTransaction();
  558. $res = $user_model->coin($user_id, -$coin, 'coin');
  559. if (!$res) {
  560. Connect::rollback();
  561. self::returnError('余额不足');
  562. }
  563. $res = $user_model->coin($to_user_id, $coin, 'coin');
  564. if (!$res) {
  565. Connect::rollback();
  566. self::returnError('赠送游戏币失败');
  567. }
  568. $coin_log_model = Model::build('coin_log');
  569. $coin1 = $user_model->coin($user_id, false, 'coin');
  570. $nick_name = $user_model->getOneById($to_user_id, 'nick_name');
  571. $nick_name = $nick_name['nick_name'];
  572. $coin_log_model->addLog($user_id, -1, -$coin, $coin1, "赠送($nick_name)游戏币");
  573. $coin2 = $user_model->coin($to_user_id, false, 'coin');
  574. $nick_name = $user_model->getOneById($user_id, 'nick_name');
  575. $nick_name = $nick_name['nick_name'];
  576. $coin_log_model->addLog($to_user_id, -1, $coin, $coin2, "收到($nick_name)游戏币");
  577. Connect::commit();
  578. api_ajax_return(
  579. [
  580. 'status' => 1,
  581. 'error' => '赠送成功',
  582. 'from_msg' => "送给你{$coin}游戏币",
  583. 'to_msg' => "收到{$coin}游戏币",
  584. 'from_score' => "",
  585. 'to_ticket' => 0,
  586. 'to_diamonds' => 0,
  587. 'to_user_id' => $to_user_id,
  588. 'prop_icon' => get_domain() . '/public/gift/jinbi.png',
  589. 'prop_id' => 0,
  590. 'total_ticket' => 0,
  591. ]
  592. );
  593. }
  594. /**
  595. * 赠送钻石
  596. * @return [type] [description]
  597. */
  598. public function sendDiamonds()
  599. {
  600. $user_id = self::getUserId();
  601. $is_nospeaking = Model::build('user')->field('is_nospeaking')->selectOne(['id' => $user_id]);
  602. $is_nospeaking = intval($is_nospeaking['is_nospeaking']);
  603. if ($is_nospeaking) {
  604. self::returnError('被im全局禁言,不能赠送钻石');
  605. }
  606. $diamonds = intval($_REQUEST['diamonds']);
  607. $to_user_id = intval($_REQUEST['to_user_id']);
  608. if (!($user_id && $to_user_id && $diamonds > 0)) {
  609. self::returnError('请输入钻石');
  610. }
  611. $user_model = Model::build('user');
  612. Connect::beginTransaction();
  613. $res = $user_model->coin($user_id, -$diamonds, 'diamonds');
  614. if (!$res) {
  615. Connect::rollback();
  616. self::returnError('余额不足');
  617. }
  618. $res = $user_model->coin($to_user_id, $diamonds, 'diamonds');
  619. if (!$res) {
  620. Connect::rollback();
  621. self::returnError('赠送钻石失败');
  622. }
  623. $coin_log_model = Model::build('coin_log');
  624. $diamonds1 = $user_model->coin($user_id, false, 'diamonds');
  625. $nick_name = $user_model->getOneById($to_user_id, 'nick_name');
  626. $nick_name = $nick_name['nick_name'];
  627. $coin_log_model->addLog($user_id, -1, -$diamonds, $diamonds1, "赠送($nick_name)钻石");
  628. $diamonds2 = $user_model->coin($to_user_id, false, 'diamonds');
  629. $nick_name = $user_model->getOneById($user_id, 'nick_name');
  630. $nick_name = $nick_name['nick_name'];
  631. $coin_log_model->addLog($to_user_id, -1, $diamonds, $diamonds2, "收到($nick_name)钻石");
  632. Connect::commit();
  633. api_ajax_return(
  634. [
  635. 'status' => 1,
  636. 'error' => '赠送成功',
  637. 'from_msg' => "送给你{$diamonds}钻石",
  638. 'to_msg' => "收到{$diamonds}钻石",
  639. 'from_score' => "",
  640. 'to_ticket' => 0,
  641. 'to_diamonds' => $diamonds,
  642. 'to_user_id' => $to_user_id,
  643. 'prop_icon' => get_domain() . '/public/images/y3.png',
  644. 'prop_id' => 0,
  645. 'total_ticket' => 0,
  646. ]
  647. );
  648. }
  649. /**
  650. * iOS日志记录
  651. * @return [type] [description]
  652. */
  653. public function pushTest()
  654. {
  655. $user_id = self::getUserId();
  656. $test_system_im = json_decode($_REQUEST['test_system_im']);
  657. fanwe_require(APP_ROOT_PATH . 'mapi/lib/tools/PushLog.class.php');
  658. PushLog::log(compact('user_id', 'test_system_im'));
  659. self::returnError('', 1);
  660. }
  661. /**
  662. * 开启上庄
  663. * @return [type] [description]
  664. */
  665. public function openBanker()
  666. {
  667. /**
  668. * 判断游戏状态
  669. */
  670. $user_id = self::getUserId();
  671. list(
  672. $video_id,
  673. $group_id
  674. ) = self::getLiveVideoByUserId($user_id);
  675. list(
  676. $last_game,
  677. $last_log_id,
  678. $banker_status,
  679. $banker_id
  680. ) = self::getLastGameByVideoId($video_id);
  681. if ($last_game) {
  682. self::returnError('上局游戏未结束');
  683. } else {
  684. $game['status'] = self::$redis->get('status');
  685. if ($game['status'] == 1) {
  686. self::returnError('上局游戏未结束');
  687. }
  688. }
  689. if (self::$redis->isVideoLock($video_id)) {
  690. self::returnError('操作频率太高了,请等下再点!');
  691. }
  692. self::$redis->lockVideo($video_id);
  693. /**
  694. * 转换游戏状态
  695. */
  696. $game = self::$redis->get($last_log_id, 'game_id');
  697. $game_id = $game['game_id'];
  698. $game = self::getGameById($game_id, 'principal');
  699. if (!$banker_status) {
  700. self::$video_redis->update_db($video_id, array('banker_status' => 1, 'principal' => $game['principal']));
  701. }
  702. /**
  703. * 群发开启上庄消息
  704. */
  705. $ext = [
  706. 'type' => 43,
  707. 'desc' => '',
  708. 'room_id' => $video_id,
  709. 'action' => 1,
  710. 'banker_status' => 1,
  711. 'data' => [
  712. 'principal' => intval($game['principal']),
  713. ],
  714. ];
  715. $res = timSystemNotify($group_id, $ext);
  716. self::pushLog(compact('res', 'ext'));
  717. self::$redis->unLockVideo($video_id);
  718. self::returnError('', 1, $ext);
  719. }
  720. /**
  721. * 主播下庄
  722. * @return [type] [description]
  723. */
  724. public function stopBanker()
  725. {
  726. /**
  727. * 判断游戏状态
  728. */
  729. $user_id = self::getUserId();
  730. list(
  731. $video_id,
  732. $group_id
  733. ) = self::getLiveVideoByUserId($user_id);
  734. list(
  735. $last_game,
  736. $last_log_id,
  737. $banker_status,
  738. $banker_id
  739. ) = self::getLastGameByVideoId($video_id);
  740. if ($last_game) {
  741. self::returnError('上局游戏未结束');
  742. }
  743. if (self::$redis->isVideoLock($video_id)) {
  744. self::returnError('操作频率太高了,请等下再点!');
  745. }
  746. self::$redis->lockVideo($video_id);
  747. /**
  748. * 返还正在上庄的玩家底金
  749. */
  750. Model::build('banker_log')->returnCoin(['video_id' => $video_id, 'status' => ['in', [1, 3]]], '主播下庄');
  751. /**
  752. * 改变上庄状态
  753. */
  754. $field = ['game_id', 'option'];
  755. $data = self::$redis->get($last_log_id, $field);
  756. $option = json_decode($data['option'], 1);
  757. list($banker_status, $banker_id, $banker_log_id, $banker_name, $banker_img, $coin, $max_bet) = self::getBankerStatus($video_id, $option);
  758. $data = [
  759. 'banker_id' => 0,
  760. 'banker_status' => 0,
  761. "banker_log_id" => 0,
  762. "banker_name" => '',
  763. "banker_img" => '',
  764. 'coin' => 0,
  765. ];
  766. self::$video_redis->update_db($video_id, $data);
  767. /**
  768. * 群发下庄消息
  769. */
  770. $ext = [
  771. 'type' => 43,
  772. 'desc' => '',
  773. 'room_id' => $video_id,
  774. 'action' => 4,
  775. 'banker_status' => 0,
  776. 'data' => [
  777. 'banker' => compact(
  778. "banker_id",
  779. "banker_log_id",
  780. "banker_name",
  781. "banker_img",
  782. 'coin'
  783. ),
  784. ],
  785. ];
  786. $res = timSystemNotify($group_id, $ext);
  787. self::pushLog(compact('res', 'ext'));
  788. self::$redis->unLockVideo($video_id);
  789. self::returnError('', 1, $ext);
  790. }
  791. /**
  792. * 申请上庄
  793. * @return [type] [description]
  794. */
  795. public function applyBanker()
  796. {
  797. $coin = intval($_REQUEST['coin']);
  798. $video_id = intval($_REQUEST['video_id']);
  799. /**
  800. * 判断游戏状态
  801. */
  802. $user_id = self::getUserId();
  803. list(
  804. $last_game,
  805. $last_log_id,
  806. $banker_status,
  807. $banker_id
  808. ) = self::getLastGameByVideoId($video_id);
  809. if ($last_game) {
  810. self::returnError('上局游戏未结束');
  811. }
  812. if (!$banker_status) {
  813. self::returnError('已关闭上庄');
  814. }
  815. if ($banker_id) {
  816. self::returnError('已上庄');
  817. }
  818. $banker_log_model = Model::build('banker_log');
  819. $log = $banker_log_model->field('id')->selectOne(
  820. [
  821. 'user_id' => $user_id,
  822. 'video_id' => $video_id,
  823. 'status' => 1,
  824. ]
  825. );
  826. if ($log) {
  827. self::returnError('已经申请上庄啦!');
  828. }
  829. $game = self::$redis->get($last_log_id, 'game_id,group_id,podcast_id');
  830. $group_id = $game['group_id'];
  831. $game_id = $game['game_id'];
  832. $podcast_id = $game['podcast_id'];
  833. $game = self::getGameById($game_id, 'principal');
  834. if ($coin < $game['principal']) {
  835. self::returnError('上庄金额不能低于底金');
  836. }
  837. if (self::$redis->isVideoLock($video_id)) {
  838. self::returnError('服务器繁忙,请等下再点!');
  839. }
  840. /**
  841. * 添加上庄申请记录
  842. */
  843. $model = Model::build('user');
  844. // $res = $model->coin($user_id, -$coin);
  845. // if (!$res) {
  846. // self::returnError('余额不足');
  847. // }
  848. $account_diamonds = $model->coin($user_id);
  849. if ($account_diamonds < $coin) {
  850. self::returnError('余额不足');
  851. }
  852. // Model::build('coin_log')->addLog($user_id, -1, -$coin, $account_diamonds, '上庄底金');
  853. $banker_log_model->addLog($video_id, $user_id, $coin);
  854. $list = $banker_log_model->getBankerList($video_id, 20);
  855. foreach ($list as $value) {
  856. if ($value['coin'] < $coin || $value['banker_id'] == $user_id) {
  857. /**
  858. * 群发申请上庄消息
  859. */
  860. $ext = [
  861. 'type' => 43,
  862. 'desc' => '',
  863. 'room_id' => $video_id,
  864. 'action' => 2,
  865. 'banker_status' => 1,
  866. 'data' => [
  867. 'banker_list' => $list,
  868. ],
  869. ];
  870. $res = timSystemNotify($group_id, $ext, [$podcast_id]);
  871. self::pushLog(compact('res', 'ext'));
  872. break;
  873. }
  874. }
  875. self::returnError('上庄成功', 1, ['coin' => $account_diamonds]);
  876. }
  877. /**
  878. * 选庄
  879. * @return [type] [description]
  880. */
  881. public function chooseBanker()
  882. {
  883. $banker_log_id = intval($_REQUEST['banker_log_id']);
  884. /**
  885. * 判断游戏状态
  886. */
  887. $user_id = self::getUserId();
  888. list(
  889. $video_id,
  890. $group_id
  891. ) = self::getLiveVideoByUserId($user_id);
  892. list(
  893. $last_game,
  894. $last_log_id,
  895. $banker_status,
  896. $banker_id
  897. ) = self::getLastGameByVideoId($video_id);
  898. if ($last_game) {
  899. self::returnError('上局游戏未结束');
  900. }
  901. if (!$banker_status) {
  902. self::returnError('已关闭上庄');
  903. }
  904. if ($banker_id) {
  905. self::returnError('已上庄');
  906. }
  907. $model = Model::build('banker_log');
  908. $banker = $model->field('user_id,coin')->selectOne(
  909. [
  910. 'id' => $banker_log_id,
  911. 'video_id' => $video_id,
  912. 'status' => 1,
  913. ]
  914. );
  915. if (!$banker) {
  916. self::returnError('数据错误');
  917. }
  918. if (self::$redis->isVideoLock($video_id)) {
  919. self::returnError('操作频率太高了,请等下再点!');
  920. }
  921. self::$redis->lockVideo($video_id);
  922. $user_model = Model::build('user');
  923. $res = $user_model->coin($banker['user_id'], -$banker['coin']);
  924. if (!$res) {
  925. // $model->update(['status' => 2], ['id' => $banker_log_id]);
  926. self::$redis->unLockVideo($video_id);
  927. self::returnError('该玩家余额不足,请重新刷新列表');
  928. }
  929. $account_diamonds = $user_model->coin($banker['user_id']);
  930. Model::build('coin_log')->addLog($banker['user_id'], -1, -$banker['coin'], $account_diamonds, '上庄底金');
  931. /**
  932. * 改变上庄状态,退还未选中上庄玩家底金
  933. */
  934. $model->chooseBanker($banker_log_id, $video_id);
  935. $user = Model::build('user')->field('nick_name,head_image')->selectOne(['id' => $banker['user_id']]);
  936. $data = [
  937. 'banker_status' => 2,
  938. "banker_id" => intval($banker['user_id']),
  939. "banker_log_id" => $banker_log_id,
  940. "banker_name" => $user['nick_name'],
  941. "banker_img" => get_spec_image($user['head_image']),
  942. 'coin' => intval($banker['coin']),
  943. ];
  944. self::$video_redis->update_db($video_id, $data);
  945. unset($data['banker_status']);
  946. /**
  947. * 群发选庄消息
  948. */
  949. $ext = [
  950. 'type' => 43,
  951. 'desc' => '',
  952. 'room_id' => $video_id,
  953. 'action' => 3,
  954. 'banker_status' => 2,
  955. 'data' => [
  956. 'banker' => $data,
  957. ],
  958. ];
  959. $res = timSystemNotify($group_id, $ext);
  960. self::pushLog(compact('res', 'ext'));
  961. self::$redis->unLockVideo($video_id);
  962. self::returnError('', 1, $ext);
  963. }
  964. /**
  965. * 申请上庄玩家列表
  966. * @return [type] [description]
  967. */
  968. public function getBankerList()
  969. {
  970. $user_id = self::getUserId();
  971. list(
  972. $video_id,
  973. $group_id
  974. ) = self::getLiveVideoByUserId($user_id);
  975. $model = Model::build('banker_log');
  976. $banker_list = $model->getBankerList($video_id, 20);
  977. self::returnError('', 1, compact('banker_list'));
  978. }
  979. /**
  980. * 获取庄家状态
  981. * @return [type] [description]
  982. */
  983. public function getBankerCoin()
  984. {
  985. $id = intval($_REQUEST['id']);
  986. $video_id = intval($_REQUEST['video_id']);
  987. if (!$id && !$video_id) {
  988. self::returnError('参数错误');
  989. }
  990. if (!$id && $video_id) {
  991. $id = intval(self::$video_redis->getOne_db($video_id, 'game_log_id'));
  992. }
  993. $field = ['game_id', 'option', 'video_id'];
  994. $data = self::$redis->get($id, $field);
  995. $option = json_decode($data['option'], 1);
  996. $video_id = intval($data['video_id']);
  997. if ($data['game_id'] === false) {
  998. self::returnError('游戏不存在');
  999. }
  1000. list($banker_status, $banker_id, $banker_log_id, $banker_name, $banker_img, $coin, $max_bet) = self::getBankerStatus($video_id, $option);
  1001. self::returnError('', 1, ['data' => compact('banker_status', 'banker_id', 'banker_log_id', 'banker_name', 'banker_img', 'coin', 'max_bet')]);
  1002. }
  1003. /**
  1004. * 弹幕消息推送
  1005. * @param [type] $room_id [description]
  1006. * @param [type] $group_id [description]
  1007. * @param [type] $podcast_id [description]
  1008. * @param [type] $user_id [description]
  1009. * @param [type] $msg [description]
  1010. * @return [type] [description]
  1011. */
  1012. protected static function popMessage($room_id, $group_id, $podcast_id, $user_id, $msg)
  1013. {
  1014. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/UserRedisService.php');
  1015. $user_redis = new UserRedisService();
  1016. $user_info = $user_redis->getRow_db($user_id, array('nick_name', 'head_image', 'user_level', 'v_icon'));
  1017. $user_info['user_id'] = $user_id;
  1018. $user_info['head_image'] = get_spec_image($user_info['head_image']);
  1019. $ext = [
  1020. 'type' => 2, //0:普通消息;1:礼物;2:弹幕消息;3:主播退出;4:禁言;5:观众进入房间;6:观众退出房间;7:直播结束
  1021. 'room_id' => $room_id, //直播ID 也是room_id;只有与当前房间相同时,收到消息才响应
  1022. 'num' => 1,
  1023. 'prop_id' => 0, //礼物id
  1024. 'icon' => '', //图片,是否要: 大中小格式?
  1025. 'user_prop_id' => 0, //红包时用到,抢红包的id
  1026. 'total_ticket' => intval($user_redis->getOne_db($podcast_id, 'ticket')), //用户总的:印票数
  1027. 'to_user_id' => 0, //礼物接收人(主播)
  1028. 'fonts_color' => '', //字体颜色
  1029. 'desc' => $msg, //弹幕消息
  1030. 'desc2' => $msg, //弹幕消息
  1031. 'sender' => $user_info,
  1032. ];
  1033. $msg_content = array(
  1034. 'MsgType' => 'TIMCustomElem',
  1035. 'MsgContent' => array(
  1036. 'Data' => json_encode($ext),
  1037. 'Desc' => '',
  1038. ),
  1039. );
  1040. fanwe_require(APP_ROOT_PATH . 'system/tim/TimApi.php');
  1041. $api = createTimAPI();
  1042. $ret = $api->group_send_group_msg2($user_id, $group_id, [$msg_content]);
  1043. }
  1044. /**
  1045. * 分销收益列表
  1046. * @return [type] [description]
  1047. */
  1048. public function getDistributionList()
  1049. {
  1050. $user_id = self::getUserId();
  1051. $data = Model::build('game_distribution')->getDistributionList($user_id);
  1052. self::returnError('', 1, compact('data'));
  1053. }
  1054. /**
  1055. * 输入邀请码(定制)
  1056. * @return [type] [description]
  1057. */
  1058. public function invitationCode()
  1059. {
  1060. $user_id = self::getUserId();
  1061. $code = trim($_REQUEST['code']);
  1062. $model = Model::build('user');
  1063. $invitation_id = $model->getInvitationBycode($code);
  1064. if ($invitation_id == $user_id || !$invitation_id) {
  1065. self::returnError('邀请码错误!');
  1066. }
  1067. if ($model->update(compact('invitation_id'), ['id' => $user_id]) === false) {
  1068. self::returnError('失败');
  1069. } else {
  1070. self::returnError('成功', 1);
  1071. }
  1072. }
  1073. /**
  1074. * 验证邀请码(定制)
  1075. * @return [type] [description]
  1076. */
  1077. public function checkCode()
  1078. {
  1079. $user_id = self::getUserId();
  1080. $m_config = load_auto_cache("m_config");
  1081. if ($m_config['enter_invitation_code']) {
  1082. $has_invitation_code = intval(Model::build('user')->getInvitationId($user_id) > 0);
  1083. } else {
  1084. $has_invitation_code = 1;
  1085. }
  1086. $invitation_tip = $m_config['enter_invitation_code_tip'];
  1087. self::returnError('', 1, compact('has_invitation_code', 'invitation_tip'));
  1088. }
  1089. public function autoStart()
  1090. {
  1091. $user_id = self::getUserId();
  1092. $auto_start = intval($_REQUEST['auto_start']);
  1093. list(
  1094. $video_id,
  1095. $group_id
  1096. ) = self::getLiveVideoByUserId($user_id);
  1097. $data = compact('auto_start');
  1098. self::$video_redis->update_db($video_id, $data);
  1099. self::returnError('', 1, $data);
  1100. }
  1101. }