robot.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use App\Model\Question;
  5. use App\Model\Option;
  6. use App\Model\User;
  7. use App\Model\RoomUser;
  8. use GuzzleHttp\Client;
  9. use GuzzleHttp\Cookie\CookieJar;
  10. use Workerman\Worker;
  11. use Workerman\Connection\AsyncTcpConnection;
  12. use Illuminate\Support\Facades\Redis;
  13. use GatewayWorker\Lib\Gateway;
  14. use Illuminate\Support\Facades\Log;
  15. class robot extends Command
  16. {
  17. /**
  18. * The name and signature of the console command.
  19. *
  20. * @var string
  21. */
  22. protected $signature = 'game:robot {user_id?}';
  23. /**
  24. * The console command description.
  25. *
  26. * @var string
  27. */
  28. protected $description = '对战机器人';
  29. /**
  30. * Create a new command instance.
  31. *
  32. * @return void
  33. */
  34. public function __construct()
  35. {
  36. parent::__construct();
  37. }
  38. /**
  39. * Execute the console command.
  40. *
  41. * @return mixed
  42. */
  43. public function handle()
  44. {
  45. global $argv;
  46. //获取机器人信息
  47. $user_id = $this->argument('user_id');
  48. // $argv[0] = '';
  49. // $argv[1] = "start";
  50. // $argv[2] = '';
  51. if(!$user_id){
  52. $user = User::inRandomOrder()->select('user_id','name')->where("is_robot", 1)->where("is_login", 0)->first();
  53. }else{
  54. // $user = User::select('user_id','name')->where("is_robot",1)->where("user_id", $user_id)->where("is_login",0)->first();
  55. $user = User::select('user_id','name')->where("is_robot",1)->where("user_id", $user_id)->first();
  56. }
  57. if(!$user){
  58. echo "未找到机器人";
  59. die;
  60. }
  61. //定义请求客户端
  62. $room_id = ''; //定义当前机器人加入的room_id
  63. $client_id = ''; //定义当前机器人client_id
  64. $worker = new Worker();
  65. $worker->onWorkerStart = function($worker) use($user, $room_id, $client_id){
  66. //定义基本信息
  67. $http_addr = env("APP_URL") . '/';
  68. // $http_addr = 'http://www.dt.com/';
  69. $client = new Client([
  70. 'cookies' => true,
  71. 'verify' => false,
  72. ]);
  73. $response = $client->request('GET', $http_addr . 'Home/User/Info', [
  74. 'query' => [
  75. 'user_id' => $user->user_id,
  76. 'mt' => 1,
  77. 'is_robot' => 1,
  78. ]
  79. ]);
  80. // $robot = $response->getBody()->getContents();
  81. $ws_connect_addr = env("WS_CONNECT_ADDR");
  82. $con = new AsyncTcpConnection("ws://{$ws_connect_addr}");
  83. // $con = new AsyncTcpConnection('ws://127.0.0.1:8282');
  84. $con->onConnect = function($con) use($client, $worker) {
  85. };
  86. $con->onMessage = function($con, $data) use($client, &$room_id, &$client_id, $user, $http_addr, $worker){
  87. //注册地址
  88. Gateway::$registerAddress = env("WS_REGEDIT_ADDR");
  89. //格式化参数
  90. $json_data = json_decode($data);
  91. //初始化
  92. if($json_data->type == 'init'){
  93. $client_id = $json_data->client_id;
  94. $response = $client->request('POST', $http_addr . 'Home/User/Bind', [
  95. 'form_params' => [
  96. 'client_id' => $client_id,
  97. ]
  98. ]);
  99. if($response->getStatusCode() != 200){
  100. echo "机器人绑定 socket失败, 结束进程\n";
  101. //结束进程
  102. $sig = 9;
  103. $master_pid = is_file($worker::$pidFile) ? file_get_contents($worker::$pidFile) : 0;
  104. $master_pid && posix_kill($master_pid, $sig);
  105. Log::info("用户ID: {$user->user_id} \n 绑定Socket失败退出进程\n");
  106. return 0;
  107. }
  108. $update_data = [
  109. "is_login" => 1,
  110. "client_id" => $client_id,
  111. ];
  112. //更新机器人登陆状态
  113. User::where("user_id", $user->user_id)->update($update_data);
  114. $result = json_decode($response->getBody()->getContents());
  115. if($result->code == 400 || ($result->code == 0 && $result->info->in_game == 1)){
  116. //结束进程
  117. $sig = 9;
  118. $master_pid = is_file($worker::$pidFile) ? file_get_contents($worker::$pidFile) : 0;
  119. $master_pid && posix_kill($master_pid, $sig);
  120. Log::info("用户ID: {$user->user_id} \n 正在游戏或者登录失败退出进程\n");
  121. return 0;
  122. }
  123. echo "client: {$client_id} 成功绑定socket\n";
  124. //启动匹配
  125. $response = $client->request('GET', $http_addr . 'Home/Game/Join',[
  126. 'form_params' => [
  127. 'client_id' => $client_id,
  128. ]
  129. ]);
  130. echo "{$client_id} 成功加入匹配\n";
  131. }
  132. //唤起匹配
  133. if($json_data->type == 'gotomatch'){
  134. $response = $client->request('GET', $http_addr . 'Home/Game/Join',[
  135. 'form_params' => [
  136. 'client_id' => $client_id,
  137. ]
  138. ]);
  139. var_dump($response->getBody()->getContents()) . "\n";
  140. echo "{$client_id} 成功加入匹配\n";
  141. }
  142. //匹配成功
  143. if($json_data->type == 'match'){
  144. $room_id = $json_data->info->room_id;
  145. echo "{$client_id} 成功加入 {$room_id} \n";
  146. }
  147. //获得题目
  148. if($json_data->type == 'question'){
  149. $question_id = $json_data->info->question->question_id;
  150. $options = $json_data->info->options;
  151. $answer = rand(0, count($json_data->info->options) - 1);
  152. //随机几秒回答问题
  153. $second = rand(0,6);
  154. sleep($second);
  155. echo "获得题目 {$json_data->info->question->question_id} : {$json_data->info->question->title}\n";
  156. $response = $client->request('POST', $http_addr . 'Home/Game/Answer',[
  157. 'form_params' => [
  158. 'question_id' => $question_id,
  159. 'option_id' => $options[$answer]->option_id,
  160. ]
  161. ]);
  162. }
  163. //结算
  164. if($json_data->type == 'round_end'){
  165. echo "回合结束,已结算";
  166. }
  167. //结算
  168. if($json_data->type == 'game_end'){
  169. $update_data['is_login'] = 0;
  170. //更新机器人登陆状态
  171. User::where("user_id", $user->user_id)->update($update_data);
  172. echo "已结算,机器人离开房间";
  173. //结束进程
  174. $sig = 9;
  175. $master_pid = is_file($worker::$pidFile) ? file_get_contents($worker::$pidFile) : 0;
  176. $master_pid && posix_kill($master_pid, $sig);
  177. $master_is_alive = $master_pid && posix_kill($master_pid, 0);
  178. if ($master_is_alive) {
  179. Log::info("用户ID: {$user->user_id} \n 房间ID: {$room_id}\n 删除不了进程 {$master_pid}\n");
  180. }
  181. exit();
  182. }
  183. };
  184. $con->connect();
  185. };
  186. Worker::runAll();
  187. }
  188. }