|
@@ -7,84 +7,17 @@ use Illuminate\Http\Request;
|
|
|
use GatewayWorker\Lib\Gateway;
|
|
|
use App\Model\Question;
|
|
|
use App\Model\Option;
|
|
|
+use App\Model\RoomUser;
|
|
|
+use App\Model\RoomQuestion;
|
|
|
+use App\Model\RoomAnswer;
|
|
|
+use App\Model\Room;
|
|
|
use Illuminate\Support\Facades\Redis;
|
|
|
+use App\Jobs\Settlement;
|
|
|
|
|
|
class GameController extends Controller
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
- * 获取问题
|
|
|
- */
|
|
|
- public function Question(Request $request)
|
|
|
- {
|
|
|
- if(!$request->session()->has('user_id')){
|
|
|
- $response['code'] = 400;
|
|
|
- $response['msg'] = '请先登录';
|
|
|
- return response()->json($response);
|
|
|
- }
|
|
|
- $room_id = $request->input('room_id');
|
|
|
- if(!$room_id){
|
|
|
- $response['code'] = 400;
|
|
|
- $response['msg'] = '缺少房间参数';
|
|
|
- return response()->json($response);
|
|
|
- }
|
|
|
- //第几题
|
|
|
- $cur_question = $request->input('cur_question');
|
|
|
- if(!$cur_question){
|
|
|
- $cur_question = 1;
|
|
|
- }
|
|
|
- //防止并发问题加文件锁
|
|
|
- $Lock_file = "{$room_id}_lock_file.txt";
|
|
|
- $i = 1;
|
|
|
- while ($i < 30) {
|
|
|
- $fp = fopen($Lock_file, "a+");
|
|
|
- if($fp===false){
|
|
|
- sleep(1);
|
|
|
- }else{
|
|
|
- flock($fp,LOCK_EX);//获取独占锁
|
|
|
- }
|
|
|
- $i++;
|
|
|
- }
|
|
|
- //获取当前房间问题
|
|
|
- $questions = Redis::get($room_id . '_questions');
|
|
|
- if($questions){
|
|
|
- $questions = json_decode($questions);
|
|
|
- }else{
|
|
|
- $questions = [];
|
|
|
- }
|
|
|
- if(isset($questions[$cur_question -1])){
|
|
|
- $response['info'] = $questions[$cur_question - 1];
|
|
|
- }else{
|
|
|
- $questions_id = [];
|
|
|
- foreach ($questions as $k => $v) {
|
|
|
- $questions_id[] = $v->question->question_id;
|
|
|
- }
|
|
|
- // $questions_id = array_column($questions, 'question_id');
|
|
|
- $question = Question::inRandomOrder()->select('question_id','title')->where("is_released",1)->whereNotIn("question_id", $questions_id)->first();
|
|
|
- $options = Option::select('option_id','title')->where("question_id",$question->question_id)->get($question->question_id);
|
|
|
- $info['question'] = $question;
|
|
|
- $info['options'] = $options;
|
|
|
- $info['questions_count'] = count($questions) + 1;
|
|
|
- $questions[] = $info;
|
|
|
- Redis::set($room_id . '_questions', json_encode($questions));
|
|
|
- $response['info'] = $info;
|
|
|
- }
|
|
|
-
|
|
|
- //解锁
|
|
|
- if($fp!==false){
|
|
|
- @flock($fp,LOCK_UN);
|
|
|
- clearstatcache();
|
|
|
- }
|
|
|
- @fclose($fp);
|
|
|
- @unlink($Lock_file);
|
|
|
-
|
|
|
- //设置返回数据
|
|
|
- $response['code'] = 0;
|
|
|
- $response['msg'] = '获取成功';
|
|
|
- return response()->json($response);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* 回答问题
|
|
|
*/
|
|
|
public function Answer(Request $request)
|
|
@@ -95,38 +28,22 @@ class GameController extends Controller
|
|
|
return response()->json($response);
|
|
|
}
|
|
|
|
|
|
- $message['is_end'] = 0; //是否结束答题标志
|
|
|
+ $answer_time = time();
|
|
|
$question_id = $request->input('question_id');
|
|
|
$option_id = $request->input('option_id');
|
|
|
$user_id = $request->session()->get('user_id');
|
|
|
|
|
|
- //检测用户断线
|
|
|
+ //注册gateway地址
|
|
|
Gateway::$registerAddress = '127.0.0.1:1238';
|
|
|
- //获取当前用户session
|
|
|
- $client_ids = Gateway::getClientIdByUid($user_id);
|
|
|
- $gateway_user = Gateway::getSession($client_ids[0]);
|
|
|
- $room_id = $gateway_user['room_id'];
|
|
|
+ //获取房间号
|
|
|
+ $room_id = RoomUser::where(["user_id"=>$user_id,"state"=>1])->value('room_id');
|
|
|
|
|
|
if(!$room_id){
|
|
|
$response['code'] = 400;
|
|
|
- $response['msg'] = '缺少房间参数';
|
|
|
+ $response['msg'] = '没有加入房间';
|
|
|
return response()->json($response);
|
|
|
}
|
|
|
|
|
|
- //获取当前房间问题条数
|
|
|
- $questions = Redis::get($room_id . '_questions');
|
|
|
- if($questions){
|
|
|
- $questions = json_decode($questions);
|
|
|
- $questions_count = count($questions);
|
|
|
- }else{
|
|
|
- $questions_count = 0;
|
|
|
- }
|
|
|
- //获取当前组存活用户
|
|
|
- $clients = Gateway::getUidListByGroup($room_id);
|
|
|
- if(count($clients) < 2){
|
|
|
- $message['is_end'] = 1;
|
|
|
- }
|
|
|
-
|
|
|
//判断答案逻辑
|
|
|
$is_true = Option::where([
|
|
|
["question_id", $question_id],
|
|
@@ -134,61 +51,92 @@ class GameController extends Controller
|
|
|
["is_answer", 1],
|
|
|
])->count();
|
|
|
|
|
|
- $scores = Redis::get($room_id.'_info');
|
|
|
- if($scores){
|
|
|
- $scores = json_decode($scores, 1);
|
|
|
+ //判断用户回答获取分数
|
|
|
+ if($is_true){
|
|
|
+ //获取当前题目开始时间
|
|
|
+ $start_at = RoomQuestion::where(["question_id" => $question_id, "room_id" => $room_id])->value('start_at');
|
|
|
+ $answer_diff = $answer_time - strtotime($start_at);
|
|
|
+ switch ($answer_diff) {
|
|
|
+ case '0':
|
|
|
+ case '1':
|
|
|
+ $score = 100;
|
|
|
+ break;
|
|
|
+ case '2':
|
|
|
+ case '3':
|
|
|
+ $score = 80;
|
|
|
+ break;
|
|
|
+ case '4':
|
|
|
+ case '5':
|
|
|
+ $score = 60;
|
|
|
+ break;
|
|
|
+ case '6':
|
|
|
+ case '7':
|
|
|
+ $score = 40;
|
|
|
+ break;
|
|
|
+ case '8':
|
|
|
+ case '9':
|
|
|
+ $score = 20;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ $score = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}else{
|
|
|
- $scores = [];
|
|
|
+ $score = 0;
|
|
|
}
|
|
|
- if(!isset($scores[$user_id])){
|
|
|
- $scores[$user_id] = 0;
|
|
|
+
|
|
|
+ //写入记录
|
|
|
+ $result = RoomAnswer::insert([
|
|
|
+ "question_id" => $question_id,
|
|
|
+ "option_id" => $option_id,
|
|
|
+ "room_id" => $room_id,
|
|
|
+ "score" => $score,
|
|
|
+ "created_at" => date('Y-m-d H:i:s'),
|
|
|
+ "updated_at" => date('Y-m-d H:i:s'),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if(!$result){
|
|
|
+ //发送消息
|
|
|
+ $response['code'] = 400;
|
|
|
+ $response['msg'] = '重复回答';
|
|
|
+ return response()->json($response);
|
|
|
}
|
|
|
|
|
|
- if($is_true && !isset($scores['questions'][$question_id][$user_id])){
|
|
|
- $scores[$user_id] = (int) $scores[$user_id] + 1;
|
|
|
+ if($score){
|
|
|
+ //增加总分
|
|
|
+ RoomUser::where([
|
|
|
+ "user_id" => $user_id,
|
|
|
+ "room_id" => $room_id,
|
|
|
+ ])->increment('score', $score);
|
|
|
}
|
|
|
- $scores['questions'][$question_id][$user_id] = $is_true;
|
|
|
|
|
|
- Redis::set($room_id . '_info', json_encode($scores));
|
|
|
- $message['is_true'] = $is_true;
|
|
|
- $message['scores'] = $scores;
|
|
|
+ $message['score'] = $score;
|
|
|
$message['user_id'] = $user_id;
|
|
|
- $message['online'] = count($clients);
|
|
|
$message['type'] = 'answer';
|
|
|
- $message['cur_quc'] = count($scores['questions'][$question_id]);
|
|
|
- $message['client_id'] = $client_ids[0];
|
|
|
- //问题超过或者到第4条为结束标志
|
|
|
- if($questions_count > 4 && $message['cur_quc'] > 1){
|
|
|
- $message['is_end'] = 1;
|
|
|
- }
|
|
|
-
|
|
|
- //发送消息
|
|
|
Gateway::sendToGroup($room_id, json_encode($message));
|
|
|
- $response['code'] = 0;
|
|
|
- $response['msg'] = '回答成功';
|
|
|
|
|
|
- //发送题目
|
|
|
- if($message['is_end'] != 1 && $message['cur_quc'] > 1){
|
|
|
- $questions_id = [];
|
|
|
- foreach ($questions as $k => $v) {
|
|
|
- $questions_id[] = $v->question->question_id;
|
|
|
+ //获取房间信息,最后一个回答触发结算程序
|
|
|
+ $room_user_limit = Room::where("room_id", $room_id)->value("user_limit");
|
|
|
+ //获取当前题目回答人数
|
|
|
+ $answer_user_count = RoomAnswer::where([
|
|
|
+ "room_id" => $room_id,
|
|
|
+ "question_id" => $question_id,
|
|
|
+ ])->count();
|
|
|
+ if($room_user_limit == $answer_user_count){
|
|
|
+ if(!isset($start_at)){
|
|
|
+ $start_at = RoomQuestion::where(["question_id" => $question_id, "room_id" => $room_id])->value('start_at');
|
|
|
}
|
|
|
- $question = Question::inRandomOrder()->select('question_id','title')->where("is_released",1)->whereNotIn("question_id", $questions_id)->first();
|
|
|
- $options = Option::select('option_id','title')->where("question_id",$question->question_id)->get($question->question_id);
|
|
|
- $info['question'] = $question;
|
|
|
- $info['options'] = $options;
|
|
|
- $info['questions_count'] = $questions_count + 1;
|
|
|
- $questions[] = $info;
|
|
|
- Redis::set($room_id . '_questions', json_encode($questions));
|
|
|
- $message = [
|
|
|
- "type" => 'question',
|
|
|
- "msg" => "获取题目成功",
|
|
|
- "info" => $info,
|
|
|
- ];
|
|
|
- Gateway::sendToGroup($room_id, json_encode($message));
|
|
|
+ $next_date = date('YmdHis', strtotime("{$start_at} +10 seconds"));
|
|
|
+ //先删除固定结算任务队列
|
|
|
+ Redis::lrem("Game_settlement_{$next_date}", $room_id);
|
|
|
+ //执行结算队列
|
|
|
+ Settlement::dispatch($room_id)->onQueue('settlement');
|
|
|
}
|
|
|
|
|
|
- //用户退出房间关闭房间等逻辑 todo ...
|
|
|
+ //发送消息
|
|
|
+ $response['code'] = 0;
|
|
|
+ $response['msg'] = '回答成功';
|
|
|
+ //返回回答信息
|
|
|
return response()->json($response);
|
|
|
}
|
|
|
|
|
@@ -204,11 +152,16 @@ class GameController extends Controller
|
|
|
}
|
|
|
|
|
|
$user_id = $request->session()->get('user_id');
|
|
|
- $username = $request->session()->get('username');
|
|
|
- $avatar = $request->session()->get('avatar');
|
|
|
- $client_id = $request->input('client_id');
|
|
|
- $data = json_encode(['user_id'=>$user_id,'level'=>'T1','avatar'=>$avatar,'username'=>$username,'client_id'=>$client_id]);
|
|
|
- Redis::lpush('match_list',$data);
|
|
|
+ //检查是否在房间中
|
|
|
+ $is_in_room = RommUser::where("user_id", $user_id)->where("state", 1)->count();
|
|
|
+ if($is_in_room){
|
|
|
+ $response['code'] = 400;
|
|
|
+ $response['msg'] = "已在房间中";
|
|
|
+ return response()->json($response);
|
|
|
+ }
|
|
|
+ //删除队列再加入匹配
|
|
|
+ Redis::lrem('match_list',$user_id);
|
|
|
+ Redis::rpush('match_list',$user_id);
|
|
|
|
|
|
$response['code'] = 0;
|
|
|
$response['msg'] = "已加入匹配队列";
|
|
@@ -216,7 +169,7 @@ class GameController extends Controller
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 退出房间
|
|
|
+ * 取消匹配
|
|
|
*/
|
|
|
public function Quit(Request $request)
|
|
|
{
|