GameController.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. namespace App\Home\Controllers;
  3. use App\Http\Controllers\Controller;
  4. use Illuminate\Http\Request;
  5. use GatewayWorker\Lib\Gateway;
  6. use App\Model\Question;
  7. use App\Model\Option;
  8. use Illuminate\Support\Facades\Redis;
  9. class GameController extends Controller
  10. {
  11. /**
  12. * 获取问题
  13. */
  14. public function Question(Request $request)
  15. {
  16. if(!$request->session()->has('user_id')){
  17. $response['code'] = 400;
  18. $response['msg'] = '请先登录';
  19. return response()->json($response);
  20. }
  21. $room_id = $request->input('room_id');
  22. if(!$room_id){
  23. $response['code'] = 400;
  24. $response['msg'] = '缺少房间参数';
  25. return response()->json($response);
  26. }
  27. //第几题
  28. $cur_question = $request->input('cur_question');
  29. if(!$cur_question){
  30. $cur_question = 1;
  31. }
  32. //防止并发问题加文件锁
  33. $Lock_file = "{$room_id}_lock_file.txt";
  34. $i = 1;
  35. while ($i < 30) {
  36. $fp = fopen($Lock_file, "a+");
  37. if($fp===false){
  38. sleep(1);
  39. }else{
  40. flock($fp,LOCK_EX);//获取独占锁
  41. }
  42. $i++;
  43. }
  44. //获取当前房间问题
  45. $questions = Redis::get($room_id . '_questions');
  46. if($questions){
  47. $questions = json_decode($questions);
  48. }else{
  49. $questions = [];
  50. }
  51. if(isset($questions[$cur_question -1])){
  52. $response['info'] = $questions[$cur_question - 1];
  53. }else{
  54. $questions_id = [];
  55. foreach ($questions as $k => $v) {
  56. $questions_id[] = $v->question->question_id;
  57. }
  58. // $questions_id = array_column($questions, 'question_id');
  59. $question = Question::inRandomOrder()->select('question_id','title')->where("is_released",1)->whereNotIn("question_id", $questions_id)->first();
  60. $options = Option::select('option_id','title')->where("question_id",$question->question_id)->get($question->question_id);
  61. $info['question'] = $question;
  62. $info['options'] = $options;
  63. $info['questions_count'] = count($questions) + 1;
  64. $questions[] = $info;
  65. Redis::set($room_id . '_questions', json_encode($questions));
  66. $response['info'] = $info;
  67. }
  68. //解锁
  69. if($fp!==false){
  70. @flock($fp,LOCK_UN);
  71. clearstatcache();
  72. }
  73. @fclose($fp);
  74. @unlink($Lock_file);
  75. //设置返回数据
  76. $response['code'] = 0;
  77. $response['msg'] = '获取成功';
  78. return response()->json($response);
  79. }
  80. /**
  81. * 回答问题
  82. */
  83. public function Answer(Request $request)
  84. {
  85. if(!$request->session()->has('user_id')){
  86. $response['code'] = 400;
  87. $response['msg'] = '请先登录';
  88. return response()->json($response);
  89. }
  90. $message['is_end'] = 0; //是否结束答题标志
  91. $question_id = $request->input('question_id');
  92. $option_id = $request->input('option_id');
  93. $user_id = $request->session()->get('user_id');
  94. //检测用户断线
  95. Gateway::$registerAddress = '127.0.0.1:1238';
  96. //获取当前用户session
  97. $client_ids = Gateway::getClientIdByUid($user_id);
  98. $gateway_user = Gateway::getSession($client_ids[0]);
  99. $room_id = $gateway_user['room_id'];
  100. if(!$room_id){
  101. $response['code'] = 400;
  102. $response['msg'] = '缺少房间参数';
  103. return response()->json($response);
  104. }
  105. //获取当前房间问题条数
  106. $questions = Redis::get($room_id . '_questions');
  107. if($questions){
  108. $questions = json_decode($questions);
  109. $questions_count = count($questions);
  110. }else{
  111. $questions_count = 0;
  112. }
  113. //获取当前组存活用户
  114. $clients = Gateway::getUidListByGroup($room_id);
  115. if(count($clients) < 2){
  116. $message['is_end'] = 1;
  117. }
  118. //判断答案逻辑
  119. $is_true = Option::where([
  120. ["question_id", $question_id],
  121. ["option_id", $option_id],
  122. ["is_answer", 1],
  123. ])->count();
  124. $scores = Redis::get($room_id.'_info');
  125. if($scores){
  126. $scores = json_decode($scores, 1);
  127. }else{
  128. $scores = [];
  129. }
  130. if(!isset($scores[$user_id])){
  131. $scores[$user_id] = 0;
  132. }
  133. if($is_true && !isset($scores['questions'][$question_id][$user_id])){
  134. $scores[$user_id] = (int) $scores[$user_id] + 1;
  135. }
  136. $scores['questions'][$question_id][$user_id] = $is_true;
  137. Redis::set($room_id . '_info', json_encode($scores));
  138. $message['is_true'] = $is_true;
  139. $message['scores'] = $scores;
  140. $message['user_id'] = $user_id;
  141. $message['online'] = count($clients);
  142. $message['type'] = 'answer';
  143. $message['cur_quc'] = count($scores['questions'][$question_id]);
  144. $message['client_id'] = $client_ids[0];
  145. //问题超过或者到第4条为结束标志
  146. if($questions_count > 4 && $message['cur_quc'] > 1){
  147. $message['is_end'] = 1;
  148. }
  149. //发送消息
  150. Gateway::sendToGroup($room_id, json_encode($message));
  151. $response['code'] = 0;
  152. $response['msg'] = '回答成功';
  153. //发送题目
  154. if($message['is_end'] != 1 && $message['cur_quc'] > 1){
  155. $questions_id = [];
  156. foreach ($questions as $k => $v) {
  157. $questions_id[] = $v->question->question_id;
  158. }
  159. $question = Question::inRandomOrder()->select('question_id','title')->where("is_released",1)->whereNotIn("question_id", $questions_id)->first();
  160. $options = Option::select('option_id','title')->where("question_id",$question->question_id)->get($question->question_id);
  161. $info['question'] = $question;
  162. $info['options'] = $options;
  163. $info['questions_count'] = $questions_count + 1;
  164. $questions[] = $info;
  165. Redis::set($room_id . '_questions', json_encode($questions));
  166. $message = [
  167. "type" => 'question',
  168. "msg" => "获取题目成功",
  169. "info" => $info,
  170. ];
  171. Gateway::sendToGroup($room_id, json_encode($message));
  172. }
  173. //用户退出房间关闭房间等逻辑 todo ...
  174. return response()->json($response);
  175. }
  176. /**
  177. * 加入房间
  178. */
  179. public function Join(Request $request)
  180. {
  181. if(!$request->session()->has('user_id')){
  182. $response['code'] = 400;
  183. $response['msg'] = '请先登录';
  184. return response()->json($response);
  185. }
  186. $user_id = $request->session()->get('user_id');
  187. $username = $request->session()->get('username');
  188. $avatar = $request->session()->get('avatar');
  189. $client_id = $request->input('client_id');
  190. $data = json_encode(['user_id'=>$user_id,'level'=>'T1','avatar'=>$avatar,'username'=>$username,'client_id'=>$client_id]);
  191. Redis::lpush('match_list',$data);
  192. $response['code'] = 0;
  193. $response['msg'] = "已加入匹配队列";
  194. return response()->json($response);
  195. }
  196. /**
  197. * 退出房间
  198. */
  199. public function Quit(Request $request)
  200. {
  201. if(!$request->session()->has('user_id')){
  202. $response['code'] = 400;
  203. $response['msg'] = '请先登录';
  204. return response()->json($response);
  205. }
  206. $username = $session->get('username');
  207. $avatar = $session->get('avatar');
  208. $user_id = $request->session()->get('user_id');
  209. $username = $request->session()->get('username');
  210. $avatar = $request->session()->get('avatar');
  211. $client_id = $request->input('client_id');
  212. $data = json_encode(['user_id'=>$user_id,'level'=>'T1','avatar'=>$avatar,'username'=>$username,'client_id'=>$client_id]);
  213. Redis::lrem('match_list',1,$data);
  214. //删除房间
  215. Redis::del('T1');
  216. $response['code'] = 0;
  217. $response['msg'] = "已取消匹配";
  218. return response()->json($response);
  219. }
  220. }