propModel.class.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. /**
  3. *
  4. */
  5. class propModel extends Model
  6. {
  7. protected static $api, $user_redis, $video_redis;
  8. public function getList($where, $field = 'id,name,score,diamonds,icon,pc_icon,pc_gif,ticket,is_much,sort,is_red_envelope,is_animated,anim_type', $order = 'diamonds desc', $limit = 3)
  9. {
  10. $where['is_effect'] = 1;
  11. return self::parseValue($this->field($field)->order($order)->limit($limit)->select($where));
  12. }
  13. protected static function parseValue($data)
  14. {
  15. if (isset($data[0])) {
  16. foreach ($data as $key => $value) {
  17. $data[$key] = self::parseValue($value);
  18. }
  19. } else {
  20. foreach ([
  21. 'icon',
  22. 'pc_icon',
  23. 'pc_gif',
  24. ] as $value) {
  25. if (isset($data[$value])) {
  26. $data[$value] = get_spec_image($data[$value]);
  27. }
  28. }
  29. foreach ([
  30. 'id',
  31. 'score',
  32. 'diamonds',
  33. 'ticket',
  34. 'is_much',
  35. 'sort',
  36. 'is_red_envelope',
  37. 'is_animated',
  38. ] as $value) {
  39. if (isset($data[$value])) {
  40. $data[$value] = intval($data[$value]);
  41. }
  42. }
  43. }
  44. return $data;
  45. }
  46. /**
  47. * 机器人定时器
  48. * @return [type] [description]
  49. */
  50. public function crontabRobot()
  51. {
  52. $m_config = load_auto_cache("m_config");
  53. // $m_config['robot_prop_num'] = 10; //送礼个数
  54. // $m_config['robot_prop_diamonds'] = 10000; //每个礼物的价值
  55. // $m_config['robot_prop_total_diamonds'] = 10000; //所有机器人礼物价值
  56. // $m_config['robot_prop_interval'] = 0; //送礼间隔
  57. // $m_config['robot_prop_real_interval'] = 0; //真人送礼间隔
  58. self::checkFile();
  59. $video_model = Model::build('video');
  60. $live_videos = $video_model->field('id')->select(['live_in' => 1]);
  61. $root = [];
  62. foreach ($live_videos as $video) {
  63. $room_id = $video['id'];
  64. // 检查机器人送礼金额
  65. $left = $m_config['robot_prop_total_diamonds'] - self::$video_redis->getOne_db($room_id, 'robot_prop_diamonds');
  66. if ($left <= 0) {
  67. $root[$room_id] = 'no_left';
  68. continue;
  69. }
  70. // 检查机器人送礼时间
  71. $lock_time = self::$video_redis->getOne_db($room_id, 'robot_prop_interval');
  72. if (!$lock_time) {
  73. $lock_time = NOW_TIME + $m_config['robot_prop_interval'];
  74. self::$video_redis->update_db($room_id, ['robot_prop_interval' => $lock_time]);
  75. }
  76. if (NOW_TIME < $lock_time) {
  77. $root[$room_id] = 'lock:' . ($lock_time - NOW_TIME);
  78. continue;
  79. }
  80. $interval = $m_config['robot_prop_interval'] + rand(-30, 30);
  81. $interval = $interval > 15 ? $interval : 15;
  82. self::$video_redis->update_db($room_id, ['robot_prop_interval' => NOW_TIME + $interval]);
  83. // 检查真人送礼时间
  84. $last_prop = Model::build('video_prop')->getNewestOne('create_time', ['video_id' => $room_id]);
  85. if (NOW_TIME < $last_prop['create_time'] + $m_config['robot_prop_real_interval']) {
  86. self::$video_redis->update_db($room_id, ['robot_prop_interval' => $last_prop['create_time'] + $m_config['robot_prop_real_interval']]);
  87. $root[$room_id] = 'real_wait';
  88. continue;
  89. }
  90. // 选取机器人
  91. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/VideoViewerRedisService.php');
  92. $video_viewer_redis = new VideoViewerRedisService();
  93. $viewer = $video_viewer_redis->get_viewer_list2($room_id, 1, 0);
  94. foreach ($viewer as $key => $value) {
  95. if (!$value['is_robot'] || !$value['user_id']) {
  96. unset($viewer[$key]);
  97. }
  98. }
  99. if (!$viewer) {
  100. // todo:模拟真实环境redis后修改
  101. // 选取数据库中的用户
  102. $viewer = Model::build('user')->field('id user_id')->select(['is_robot' => 1]);
  103. }
  104. $user_id = intval($viewer[array_rand($viewer, 1)]['user_id']);
  105. // 选取礼物
  106. $num = rand(1, intval($m_config['robot_prop_num']));
  107. $max = intval($left / $num);
  108. $max = $m_config['robot_prop_diamonds'] > $max ? $max : intval($m_config['robot_prop_diamonds']);
  109. $prop = $this->field('id,ticket')->select(['diamonds' => ['between', [1, $max]], 'is_red_envelope' => 0, 'is_effect' => 1]);
  110. $prop_key = array_rand($prop, 1);
  111. $prop_id = intval($prop[$prop_key]['id']);
  112. if (!$prop_id) {
  113. $root[$room_id] = 'no_prop:' . $max;
  114. continue;
  115. }
  116. // 伪造礼物印票
  117. self::$video_redis->inc_field($room_id, 'robot_prop_diamonds', $prop[$prop_key]['ticket'] * $num);
  118. self::$user_redis->inc_field($podcast_id, 'ticket', $prop[$prop_key]['ticket'] * $num);
  119. // 伪造礼物推送
  120. $ret = self::sendPropMsg($user_id, $prop_id, $room_id, $num);
  121. if (IS_DEBUG) {
  122. $root[$room_id] = $ret;
  123. } else {
  124. $root[$room_id] = $ret['ActionStatus'];
  125. }
  126. }
  127. return $root;
  128. }
  129. /**
  130. * 检测方法
  131. * @return [type] [description]
  132. */
  133. protected static function checkFile()
  134. {
  135. if (!self::$api) {
  136. fanwe_require(APP_ROOT_PATH . 'system/tim/TimApi.php');
  137. self::$api = createTimAPI();
  138. }
  139. if (!self::$user_redis) {
  140. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/BaseRedisService.php');
  141. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/UserRedisService.php');
  142. self::$user_redis = new UserRedisService();
  143. }
  144. if (!self::$video_redis) {
  145. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/BaseRedisService.php');
  146. fanwe_require(APP_ROOT_PATH . 'mapi/lib/redis/VideoRedisService.php');
  147. self::$video_redis = new VideoRedisService();
  148. }
  149. }
  150. /**
  151. * 赠送礼物推送消息
  152. * @param [type] $user_id 赠送人id
  153. * @param [type] $prop_id [description]
  154. * @param [type] $room_id [description]
  155. * @param integer $num [description]
  156. * @param boolean $plus_num [description]
  157. * @return [type] [description]
  158. */
  159. protected static function sendPropMsg($user_id, $prop_id, $room_id, $num = 1, $plus_num = false, $to_user_id = false)
  160. {
  161. self::checkFile();
  162. $prop = load_auto_cache("prop_id", ['id' => $prop_id]);
  163. $user = self::$user_redis->getRow_db($user_id, array('nick_name', 'head_image', 'user_level', 'v_icon'));
  164. $video = self::$video_redis->getRow_db($room_id, ['id', 'podcast_id', 'group_id', 'prop_table', 'room_type']);
  165. $to_user_id = $to_user_id ? $to_user_id : $video['podcast_id'];
  166. $res = [];
  167. for ($i = 0; $i < $num; $i++) {
  168. $plus_num = ($plus_num && $num == 1) ? $plus_num : ($prop['is_much'] ? ($i + 1) : 1);
  169. $ext = [
  170. 'type' => 1, //0:普通消息;1:礼物;2:弹幕消息;3:主播退出;4:禁言;5:观众进入房间;6:观众退出房间;7:直播结束; 8:红包
  171. 'num' => $num, //数量
  172. 'is_plus' => $prop['is_much'], //1:数量连续叠加显示;0:不叠加;这个值是从客户端上传过来的
  173. 'is_much' => $prop['is_much'], //1:可以连续发送多个;用于小金额礼物
  174. 'room_id' => $room_id,
  175. 'plus_num' => $plus_num,
  176. 'app_plus_num' => $plus_num,
  177. 'is_animated' => $prop['is_animated'],
  178. 'sender' => [
  179. 'user_id' => $user_id,
  180. 'nick_name' => $user['nick_name'],
  181. 'head_image' => get_spec_image($user['head_image']),
  182. 'user_level' => $user['user_level'],
  183. 'v_icon' => $user['v_icon'],
  184. ],
  185. 'prop_id' => $prop_id,
  186. 'icon' => $prop['icon'],
  187. 'user_prop_id' => 0, //插入video_prop的礼物id
  188. 'total_ticket' => intval(self::$user_redis->getOne_db($podcast_id, 'ticket')), //伪造总印票数
  189. 'to_user_id' => $video['podcast_id'],
  190. 'fonts_color' => '',
  191. 'desc' => "我送了1个" . $prop['name'], //谁送了谁多少个什么
  192. 'desc2' => "我送了1个" . $prop['name'], //我送了谁多少个什么
  193. 'anim_type' => $prop['anim_type'],
  194. 'top_title' => $user['nick_name'] . "送了," . $prop['name'],
  195. 'anim_cfg' => $prop['anim_cfg'],
  196. ];
  197. $msg_content = [
  198. 'MsgType' => 'TIMCustomElem', //自定义类型
  199. 'MsgContent' => [
  200. 'Data' => json_encode($ext),
  201. 'Desc' => '',
  202. ],
  203. ];
  204. $res[] = [
  205. 'ret' => self::$api->group_send_group_msg2($user_id, $video['group_id'], [$msg_content]),
  206. 'ext' => $ext,
  207. 'user_id' => $user_id,
  208. 'prop_id' => $prop_id,
  209. 'group_id' => $video['group_id'],
  210. ];
  211. }
  212. return $res;
  213. }
  214. }