RelayController.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <?php
  2. namespace App\Controllers;
  3. use App\Models\Relay;
  4. use App\Models\Node;
  5. use App\Models\User;
  6. use App\Services\Auth;
  7. use App\Utils\Tools;
  8. use App\Services\Config;
  9. use ArrayObject;
  10. class RelayController extends UserController
  11. {
  12. public function index($request, $response, $args)
  13. {
  14. $pageNum = 1;
  15. $user = Auth::getUser();
  16. if (isset($request->getQueryParams()['page'])) {
  17. $pageNum = $request->getQueryParams()['page'];
  18. }
  19. $logs = Relay::where('user_id', $user->id)->orwhere('user_id', 0)->paginate(15, ['*'], 'page', $pageNum);
  20. $logs->setPath('/user/relay');
  21. $is_relay_able = Tools::is_protocol_relay($user);
  22. //链路表部分
  23. $nodes = Node::where(
  24. static function ($query) use ($user) {
  25. $query->Where('node_group', '=', $user->node_group)
  26. ->orWhere('node_group', '=', 0);
  27. }
  28. )->where('type', 1)->where(
  29. static function ($query) {
  30. $query->Where('sort', 10)
  31. ->orWhere('sort', 12);
  32. }
  33. )->where('node_class', '<=', $user->class)->orderBy('name')->get();
  34. $pathset = new ArrayObject();
  35. $relay_rules = Relay::where('user_id', $user->id)->orwhere('user_id', 0)->get();
  36. $mu_nodes = Node::where('sort', 9)->where('node_class', '<=', $user->class)->where('type', '1')->where(
  37. static function ($query) use ($user) {
  38. $query->where('node_group', '=', $user->node_group)
  39. ->orWhere('node_group', '=', 0);
  40. }
  41. )->get();
  42. foreach ($nodes as $node) {
  43. if ($node->mu_only == 0) {
  44. $relay_rule = Tools::pick_out_relay_rule($node->id, $user->port, $relay_rules);
  45. if ($relay_rule != null) {
  46. $pathset = Tools::insertPathRule($relay_rule, $pathset, $user->port);
  47. }
  48. }
  49. if ($node->custom_rss == 1) {
  50. foreach ($mu_nodes as $mu_node) {
  51. $mu_user = User::where('port', '=', $mu_node->server)->first();
  52. if ($mu_user == null) {
  53. continue;
  54. }
  55. if (!($mu_user->class >= $node->node_class && ($node->node_group == 0 || $node->node_group == $mu_user->node_group))) {
  56. continue;
  57. }
  58. if ($mu_user->is_multi_user != 2) {
  59. $relay_rule = Tools::pick_out_relay_rule($node->id, $mu_user->port, $relay_rules);
  60. if ($relay_rule != null) {
  61. $pathset = Tools::insertPathRule($relay_rule, $pathset, $mu_user->port);
  62. }
  63. }
  64. }
  65. }
  66. }
  67. foreach ($pathset as $path) {
  68. foreach ($pathset as $index => $single_path) {
  69. if ($path != $single_path && $path->port == $single_path->port) {
  70. if ($single_path->end_node->id == $path->begin_node->id) {
  71. $path->begin_node = $single_path->begin_node;
  72. if ($path->begin_node->isNodeAccessable() == false) {
  73. $path->path = '<font color="#FF0000">' . $single_path->begin_node->name . '</font>' . ' → ' . $path->path;
  74. $path->status = '阻断';
  75. } else {
  76. $path->path = $single_path->begin_node->name . ' → ' . $path->path;
  77. $path->status = '通畅';
  78. }
  79. $pathset->offsetUnset($index);
  80. continue;
  81. }
  82. if ($path->end_node->id == $single_path->begin_node->id) {
  83. $path->end_node = $single_path->end_node;
  84. if ($single_path->end_node->isNodeAccessable() == false) {
  85. $path->path = $path->path . ' → ' . '<font color="#FF0000">' . $single_path->end_node->name . '</font>';
  86. $path->status = '阻断';
  87. } else {
  88. $path->path = $path->path . ' → ' . $single_path->end_node->name;
  89. }
  90. $pathset->offsetUnset($index);
  91. continue;
  92. }
  93. }
  94. }
  95. }
  96. return $this->view()->assign('rules', $logs)->assign('relay_able_protocol_list', Config::getSupportParam('relay_able_protocol'))->assign('is_relay_able', $is_relay_able)->assign('pathset', $pathset)->display('user/relay/index.tpl');
  97. }
  98. public function create($request, $response, $args)
  99. {
  100. $user = Auth::getUser();
  101. $source_nodes = Node::where(
  102. static function ($query) use ($user) {
  103. $query->Where('node_group', '=', $user->node_group)
  104. ->orWhere('node_group', '=', 0);
  105. }
  106. )->where('type', 1)->where(
  107. static function ($query) {
  108. $query->Where('sort', 10)
  109. ->orWhere('sort', 12);
  110. }
  111. )->where('node_class', '<=', $user->class)->orderBy('name')->get();
  112. foreach ($source_nodes as $node) {
  113. if ($node->sort == 12) {
  114. $node->name .= ' 正在使用V2ray后端 ';
  115. }
  116. }
  117. $dist_nodes = Node::where(
  118. static function ($query) use ($user) {
  119. $query->Where('node_group', '=', $user->node_group)
  120. ->orWhere('node_group', '=', 0);
  121. }
  122. )->where('type', 1)->where(
  123. static function ($query) {
  124. $query->Where('sort', 0)
  125. ->orWhere('sort', 10)
  126. ->orWhere('sort', 11)
  127. ->orWhere('sort', 12);
  128. }
  129. )->where('node_class', '<=', $user->class)->orderBy('name')->get();
  130. $ports_raw = Node::where(
  131. static function ($query) use ($user) {
  132. $query->Where('node_group', '=', $user->node_group)
  133. ->orWhere('node_group', '=', 0);
  134. }
  135. )->where('type', 1)->where('sort', 9)->where('node_class', '<=', $user->class)->orderBy('name')->get();
  136. $ports = array();
  137. foreach ($ports_raw as $port_raw) {
  138. $mu_user = User::where('port', $port_raw->server)->first();
  139. if ($mu_user->is_multi_user == 1) {
  140. $ports[] = $port_raw->server;
  141. }
  142. }
  143. foreach ($dist_nodes as $node) {
  144. if ($node->sort == 11 || $node->sort == 12) {
  145. $node_explode = Tools::ssv2Array($node->server);
  146. $ports[] = $node_explode['port'];
  147. $node->name = $node->name . ' 如果是V2ray后端 请设置成 ' . $node_explode['port'];
  148. } else {
  149. $node->name = $node->name . ' 如果是V2ray后端 请设置成 ' . $user->port;
  150. }
  151. }
  152. $ports[] = $user->port;
  153. $ports = array_unique($ports);
  154. return $this->view()->assign('source_nodes', $source_nodes)->assign('dist_nodes', $dist_nodes)->assign('ports', $ports)->display('user/relay/add.tpl');
  155. }
  156. public function add($request, $response, $args)
  157. {
  158. $user = Auth::getUser();
  159. $dist_node_id = $request->getParam('dist_node');
  160. $source_node_id = $request->getParam('source_node');
  161. $port = $request->getParam('port');
  162. $priority = $request->getParam('priority');
  163. $source_node = Node::where('id', $source_node_id)->where(
  164. static function ($query) use ($user) {
  165. $query->Where('node_group', '=', $user->node_group)
  166. ->orWhere('node_group', '=', 0);
  167. }
  168. )->where('type', 1)->where(
  169. static function ($query) {
  170. $query->Where('sort', 10)
  171. ->orWhere('sort', 12);
  172. }
  173. )->where('node_class', '<=', $user->class)->first();
  174. if ($source_node == null) {
  175. $rs['ret'] = 0;
  176. $rs['msg'] = '起源节点错误';
  177. return $response->getBody()->write(json_encode($rs));
  178. }
  179. if ($source_node->sort == 12) {
  180. $rules = Relay::Where('source_node_id', $source_node_id)->get();
  181. foreach ($rules as $rule) {
  182. if ($rule['user_id'] == 0 || $rule['user_id'] = $user->id) {
  183. $rs['ret'] = 0;
  184. $rs['msg'] = 'v2ray中转一个起点一个rule';
  185. return $response->getBody()->write(json_encode($rs));
  186. }
  187. }
  188. }
  189. $dist_node = Node::where('id', $dist_node_id)->where(
  190. static function ($query) use ($user) {
  191. $query->Where('node_group', '=', $user->node_group)
  192. ->orWhere('node_group', '=', 0);
  193. }
  194. )->where('type', 1)->where(
  195. static function ($query) {
  196. $query->Where('sort', 0)
  197. ->orWhere('sort', 10)
  198. ->orWhere('sort', 11)
  199. ->orWhere('sort', 12);
  200. }
  201. )->where('node_class', '<=', $user->class)->first();
  202. if ($dist_node_id == -1) {
  203. $dist_node = new Node();
  204. $dist_node->id = -1;
  205. $dist_node->node_ip = '0.0.0.0';
  206. $dist_node->sort = 10;
  207. }
  208. if ($dist_node == null) {
  209. $rs['ret'] = 0;
  210. $rs['msg'] = '目标节点错误';
  211. return $response->getBody()->write(json_encode($rs));
  212. }
  213. $port_raw = Node::where('server', $port)->where(
  214. static function ($query) use ($user) {
  215. $query->Where('node_group', '=', $user->node_group)
  216. ->orWhere('node_group', '=', 0);
  217. }
  218. )->where('type', 1)->where('sort', 9)->where('node_class', '<=', $user->class)->first();
  219. $v2ray_port_raw = '';
  220. if ($dist_node->sort == 12 || $dist_node->sort == 11) {
  221. $node_explode = Tools::ssv2Array($dist_node->server);
  222. $v2ray_port_raw = $node_explode['port'];
  223. }
  224. if (($port_raw == null && $port != $user->port && $v2ray_port_raw == '') || ($v2ray_port_raw != '' && ($port != $user->port && $port != $v2ray_port_raw))) {
  225. $rs['ret'] = 0;
  226. $rs['msg'] = '端口错误';
  227. return $response->getBody()->write(json_encode($rs));
  228. }
  229. if (!Tools::is_protocol_relay($user)) {
  230. $rs['ret'] = 0;
  231. $rs['msg'] = "为了中转的稳定,您需要在<a href='/user/edit'>资料编辑</a>处设置协议为 auth_aes128_md5 或 auth_aes128_sha1 后方可设置中转规则!";
  232. return $response->getBody()->write(json_encode($rs));
  233. }
  234. $rule = new Relay();
  235. $rule->user_id = $user->id;
  236. $rule->dist_node_id = $dist_node_id;
  237. $dist_node_ip = Tools::getRelayNodeIp($source_node, $dist_node);
  238. $rule->dist_ip = $dist_node_ip;
  239. $rule->source_node_id = $source_node_id;
  240. $rule->port = $port;
  241. $rule->priority = min($priority, 99998);
  242. $ruleset = Relay::where('user_id', $user->id)->orwhere('user_id', 0)->get();
  243. $maybe_rule_id = Tools::has_conflict_rule($rule, $ruleset, 0, $rule->source_node_id);
  244. if ($maybe_rule_id != 0) {
  245. $rs['ret'] = 0;
  246. $rs['msg'] = '您即将添加的规则与规则 ID:' . $maybe_rule_id . ' 冲突!';
  247. if ($maybe_rule_id == -1) {
  248. $rs['msg'] = '您即将添加的规则可能会造成冲突!';
  249. }
  250. return $response->getBody()->write(json_encode($rs));
  251. }
  252. if (!$rule->save()) {
  253. $rs['ret'] = 0;
  254. $rs['msg'] = '添加失败';
  255. return $response->getBody()->write(json_encode($rs));
  256. }
  257. $rs['ret'] = 1;
  258. $rs['msg'] = '添加成功';
  259. return $response->getBody()->write(json_encode($rs));
  260. }
  261. public function edit($request, $response, $args)
  262. {
  263. $id = $args['id'];
  264. $user = Auth::getUser();
  265. $rule = Relay::where('id', $id)->where('user_id', $user->id)->first();
  266. if ($rule == null) {
  267. exit(0);
  268. }
  269. $user = Auth::getUser();
  270. $source_nodes = Node::where(
  271. static function ($query) use ($user) {
  272. $query->Where('node_group', '=', $user->node_group)
  273. ->orWhere('node_group', '=', 0);
  274. }
  275. )->where('type', 1)->where(
  276. static function ($query) {
  277. $query->Where('sort', 10)
  278. ->orWhere('sort', 12);
  279. }
  280. )->where('node_class', '<=', $user->class)->orderBy('name')->get();
  281. foreach ($source_nodes as $node) {
  282. if ($node->sort == 12) {
  283. $node->name .= ' 正在使用V2ray后端 ';
  284. }
  285. }
  286. $dist_nodes = Node::where(
  287. static function ($query) use ($user) {
  288. $query->Where('node_group', '=', $user->node_group)
  289. ->orWhere('node_group', '=', 0);
  290. }
  291. )->where('type', 1)->where(
  292. static function ($query) {
  293. $query->Where('sort', 0)
  294. ->orWhere('sort', 10)
  295. ->orWhere('sort', 11)
  296. ->orWhere('sort', 12);
  297. }
  298. )->where('node_class', '<=', $user->class)->orderBy('name')->get();
  299. $ports_raw = Node::where(
  300. static function ($query) use ($user) {
  301. $query->Where('node_group', '=', $user->node_group)
  302. ->orWhere('node_group', '=', 0);
  303. }
  304. )->where('type', 1)->where('sort', 9)->where('node_class', '<=', $user->class)->orderBy('name')->get();
  305. $ports = array();
  306. foreach ($ports_raw as $port_raw) {
  307. $mu_user = User::where('port', $port_raw->server)->first();
  308. if ($mu_user->is_multi_user == 1) {
  309. $ports[] = $port_raw->server;
  310. }
  311. }
  312. foreach ($dist_nodes as $node) {
  313. if ($node->sort == 11 || $node->sort == 12) {
  314. $node_explode = Tools::ssv2Array($node->server);
  315. $ports[] = $node_explode['port'];
  316. $node->name = $node->name . ' 如果是V2ray后端 请设置成: ' . $node_explode['port'];
  317. } else {
  318. $node->name = $node->name . ' 如果是V2ray后端 请设置成 ' . $user->port;
  319. }
  320. }
  321. $ports[] = $user->port;
  322. $ports = array_unique($ports);
  323. return $this->view()->assign('rule', $rule)->assign('source_nodes', $source_nodes)->assign('dist_nodes', $dist_nodes)->assign('ports', $ports)->display('user/relay/edit.tpl');
  324. }
  325. public function update($request, $response, $args)
  326. {
  327. $id = $args['id'];
  328. $user = Auth::getUser();
  329. $rule = Relay::where('id', $id)->where('user_id', $user->id)->first();
  330. if ($rule == null) {
  331. exit(0);
  332. }
  333. $dist_node_id = $request->getParam('dist_node');
  334. $source_node_id = $request->getParam('source_node');
  335. $port = $request->getParam('port');
  336. $priority = $request->getParam('priority');
  337. $source_node = Node::where('id', $source_node_id)->where(
  338. static function ($query) use ($user) {
  339. $query->Where('node_group', '=', $user->node_group)
  340. ->orWhere('node_group', '=', 0);
  341. }
  342. )->where('type', 1)->where(
  343. static function ($query) {
  344. $query->Where('sort', 10)
  345. ->orWhere('sort', 12);
  346. }
  347. )->where('node_class', '<=', $user->class)->first();
  348. if ($source_node == null) {
  349. $rs['ret'] = 0;
  350. $rs['msg'] = '起源节点错误';
  351. return $response->getBody()->write(json_encode($rs));
  352. }
  353. $dist_node = Node::where('id', $dist_node_id)->where(
  354. static function ($query) use ($user) {
  355. $query->Where('node_group', '=', $user->node_group)
  356. ->orWhere('node_group', '=', 0);
  357. }
  358. )->where('type', 1)->where(
  359. static function ($query) {
  360. $query->Where('sort', 0)
  361. ->orWhere('sort', 10)
  362. ->orWhere('sort', 11)
  363. ->orWhere('sort', 12);
  364. }
  365. )->where('node_class', '<=', $user->class)->first();
  366. if ($dist_node_id == -1) {
  367. $dist_node = new Node();
  368. $dist_node->id = -1;
  369. $dist_node->node_ip = '0.0.0.0';
  370. $dist_node->sort = 10;
  371. }
  372. if ($dist_node == null) {
  373. $rs['ret'] = 0;
  374. $rs['msg'] = '目标节点错误';
  375. return $response->getBody()->write(json_encode($rs));
  376. }
  377. $port_raw = Node::where('server', $port)->where(
  378. static function ($query) use ($user) {
  379. $query->Where('node_group', '=', $user->node_group)
  380. ->orWhere('node_group', '=', 0);
  381. }
  382. )->where('type', 1)->where('sort', 9)->where('node_class', '<=', $user->class)->first();
  383. $v2ray_port_raw = '';
  384. if ($dist_node->sort == 12 || $dist_node->sort == 11) {
  385. $node_explode = Tools::ssv2Array($dist_node->server);
  386. $v2ray_port_raw = $node_explode['port'];
  387. }
  388. if (($port_raw == null && $port != $user->port && $v2ray_port_raw == '') || ($v2ray_port_raw != '' && ($port != $user->port && $port != $v2ray_port_raw))) {
  389. $rs['ret'] = 0;
  390. $rs['msg'] = '端口错误';
  391. return $response->getBody()->write(json_encode($rs));
  392. }
  393. if (!Tools::is_protocol_relay($user)) {
  394. $rs['ret'] = 0;
  395. $rs['msg'] = "为了中转的稳定,您需要在<a href='/user/edit'>资料编辑</a>处设置协议为 auth_aes128_md5 或 auth_aes128_sha1 后方可设置中转规则!";
  396. return $response->getBody()->write(json_encode($rs));
  397. }
  398. $rule->user_id = $user->id;
  399. $rule->dist_node_id = $dist_node_id;
  400. $dist_node_ip = Tools::getRelayNodeIp($source_node, $dist_node);
  401. $rule->dist_ip = $dist_node_ip;
  402. $rule->source_node_id = $source_node_id;
  403. $rule->port = $port;
  404. $rule->priority = min($priority, 99998);
  405. $ruleset = Relay::where('user_id', $user->id)->orwhere('user_id', 0)->get();
  406. $maybe_rule_id = Tools::has_conflict_rule($rule, $ruleset, $rule->id, $rule->source_node_id);
  407. if ($maybe_rule_id != 0) {
  408. $rs['ret'] = 0;
  409. $rs['msg'] = '您即将添加的规则与规则 ID:' . $maybe_rule_id . ' 冲突!';
  410. if ($maybe_rule_id == -1) {
  411. $rs['msg'] = '您即将添加的规则可能会造成冲突!';
  412. }
  413. return $response->getBody()->write(json_encode($rs));
  414. }
  415. if (!$rule->save()) {
  416. $rs['ret'] = 0;
  417. $rs['msg'] = '修改失败';
  418. return $response->getBody()->write(json_encode($rs));
  419. }
  420. $rs['ret'] = 1;
  421. $rs['msg'] = '修改成功';
  422. return $response->getBody()->write(json_encode($rs));
  423. }
  424. public function delete($request, $response, $args)
  425. {
  426. $id = $request->getParam('id');
  427. $user = Auth::getUser();
  428. $rule = Relay::where('id', $id)->where('user_id', $user->id)->first();
  429. if ($rule == null) {
  430. exit(0);
  431. }
  432. if (!$rule->delete()) {
  433. $rs['ret'] = 0;
  434. $rs['msg'] = '删除失败';
  435. return $response->getBody()->write(json_encode($rs));
  436. }
  437. $rs['ret'] = 1;
  438. $rs['msg'] = '删除成功';
  439. return $response->getBody()->write(json_encode($rs));
  440. }
  441. }