ServerService.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. namespace App\Services;
  3. use App\Models\ServerLog;
  4. use App\Models\ServerRoute;
  5. use App\Models\ServerShadowsocks;
  6. use App\Models\User;
  7. use App\Models\ServerV2ray;
  8. use App\Models\ServerTrojan;
  9. use App\Utils\CacheKey;
  10. use App\Utils\Helper;
  11. use Illuminate\Support\Facades\Cache;
  12. class ServerService
  13. {
  14. public function getV2ray(User $user, $all = false):array
  15. {
  16. $servers = [];
  17. $model = ServerV2ray::orderBy('sort', 'ASC');
  18. if (!$all) {
  19. $model->where('show', 1);
  20. }
  21. $v2ray = $model->get();
  22. for ($i = 0; $i < count($v2ray); $i++) {
  23. $v2ray[$i]['type'] = 'v2ray';
  24. $groupId = $v2ray[$i]['group_id'];
  25. if (!in_array($user->group_id, $groupId)) continue;
  26. if (strpos($v2ray[$i]['port'], '-') !== false) {
  27. $v2ray[$i]['port'] = Helper::randomPort($v2ray[$i]['port']);
  28. }
  29. if ($v2ray[$i]['parent_id']) {
  30. $v2ray[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $v2ray[$i]['parent_id']));
  31. } else {
  32. $v2ray[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $v2ray[$i]['id']));
  33. }
  34. array_push($servers, $v2ray[$i]->toArray());
  35. }
  36. return $servers;
  37. }
  38. public function getTrojan(User $user, $all = false):array
  39. {
  40. $servers = [];
  41. $model = ServerTrojan::orderBy('sort', 'ASC');
  42. if (!$all) {
  43. $model->where('show', 1);
  44. }
  45. $trojan = $model->get();
  46. for ($i = 0; $i < count($trojan); $i++) {
  47. $trojan[$i]['type'] = 'trojan';
  48. $groupId = $trojan[$i]['group_id'];
  49. if (!in_array($user->group_id, $groupId)) continue;
  50. if (strpos($trojan[$i]['port'], '-') !== false) {
  51. $trojan[$i]['port'] = Helper::randomPort($trojan[$i]['port']);
  52. }
  53. if ($trojan[$i]['parent_id']) {
  54. $trojan[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojan[$i]['parent_id']));
  55. } else {
  56. $trojan[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojan[$i]['id']));
  57. }
  58. array_push($servers, $trojan[$i]->toArray());
  59. }
  60. return $servers;
  61. }
  62. public function getShadowsocks(User $user, $all = false)
  63. {
  64. $servers = [];
  65. $model = ServerShadowsocks::orderBy('sort', 'ASC');
  66. if (!$all) {
  67. $model->where('show', 1);
  68. }
  69. $shadowsocks = $model->get();
  70. for ($i = 0; $i < count($shadowsocks); $i++) {
  71. $shadowsocks[$i]['type'] = 'shadowsocks';
  72. $groupId = $shadowsocks[$i]['group_id'];
  73. if (!in_array($user->group_id, $groupId)) continue;
  74. if (strpos($shadowsocks[$i]['port'], '-') !== false) {
  75. $shadowsocks[$i]['port'] = Helper::randomPort($shadowsocks[$i]['port']);
  76. }
  77. if ($shadowsocks[$i]['parent_id']) {
  78. $shadowsocks[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $shadowsocks[$i]['parent_id']));
  79. } else {
  80. $shadowsocks[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $shadowsocks[$i]['id']));
  81. }
  82. array_push($servers, $shadowsocks[$i]->toArray());
  83. }
  84. return $servers;
  85. }
  86. public function getAvailableServers(User $user, $all = false)
  87. {
  88. $servers = array_merge(
  89. $this->getShadowsocks($user, $all),
  90. $this->getV2ray($user, $all),
  91. $this->getTrojan($user, $all)
  92. );
  93. $tmp = array_column($servers, 'sort');
  94. array_multisort($tmp, SORT_ASC, $servers);
  95. $servers = array_map(function ($server) {
  96. $server['port'] = (int)$server['port'];
  97. $server['is_online'] = (time() - 300 > $server['last_check_at']) ? 0 : 1;
  98. return $server;
  99. }, $servers);
  100. return $servers;
  101. }
  102. public function getAvailableUsers($groupId)
  103. {
  104. return User::whereIn('group_id', $groupId)
  105. ->whereRaw('u + d < transfer_enable')
  106. ->where(function ($query) {
  107. $query->where('expired_at', '>=', time())
  108. ->orWhere('expired_at', NULL);
  109. })
  110. ->where('banned', 0)
  111. ->select([
  112. 'id',
  113. 'uuid',
  114. 'speed_limit'
  115. ])
  116. ->get();
  117. }
  118. public function log(int $userId, int $serverId, int $u, int $d, float $rate, string $method)
  119. {
  120. if (($u + $d) < 10240) return true;
  121. $timestamp = strtotime(date('Y-m-d'));
  122. $serverLog = ServerLog::where('log_at', '>=', $timestamp)
  123. ->where('log_at', '<', $timestamp + 3600)
  124. ->where('server_id', $serverId)
  125. ->where('user_id', $userId)
  126. ->where('rate', $rate)
  127. ->where('method', $method)
  128. ->first();
  129. if ($serverLog) {
  130. try {
  131. $serverLog->increment('u', $u);
  132. $serverLog->increment('d', $d);
  133. return true;
  134. } catch (\Exception $e) {
  135. return false;
  136. }
  137. } else {
  138. $serverLog = new ServerLog();
  139. $serverLog->user_id = $userId;
  140. $serverLog->server_id = $serverId;
  141. $serverLog->u = $u;
  142. $serverLog->d = $d;
  143. $serverLog->rate = $rate;
  144. $serverLog->log_at = $timestamp;
  145. $serverLog->method = $method;
  146. return $serverLog->save();
  147. }
  148. }
  149. public function getShadowsocksServers()
  150. {
  151. $server = ServerShadowsocks::orderBy('sort', 'ASC')->get();
  152. for ($i = 0; $i < count($server); $i++) {
  153. $server[$i]['type'] = 'shadowsocks';
  154. }
  155. return $server->toArray();
  156. }
  157. public function getV2rayServers()
  158. {
  159. $server = ServerV2ray::orderBy('sort', 'ASC')->get();
  160. for ($i = 0; $i < count($server); $i++) {
  161. $server[$i]['type'] = 'v2ray';
  162. }
  163. return $server->toArray();
  164. }
  165. public function getTrojanServers()
  166. {
  167. $server = ServerTrojan::orderBy('sort', 'ASC')->get();
  168. for ($i = 0; $i < count($server); $i++) {
  169. $server[$i]['type'] = 'trojan';
  170. }
  171. return $server->toArray();
  172. }
  173. private function mergeData(&$servers)
  174. {
  175. foreach ($servers as $k => $v) {
  176. $serverType = strtoupper($servers[$k]['type']);
  177. $servers[$k]['online'] = Cache::get(CacheKey::get("SERVER_{$serverType}_ONLINE_USER", $servers[$k]['parent_id'] ? $servers[$k]['parent_id'] : $servers[$k]['id']));
  178. if ($servers[$k]['parent_id']) {
  179. $servers[$k]['last_check_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_CHECK_AT", $servers[$k]['parent_id']));
  180. $servers[$k]['last_push_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_PUSH_AT", $servers[$k]['parent_id']));
  181. } else {
  182. $servers[$k]['last_check_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_CHECK_AT", $servers[$k]['id']));
  183. $servers[$k]['last_push_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_PUSH_AT", $servers[$k]['id']));
  184. }
  185. if ((time() - 300) >= $servers[$k]['last_check_at']) {
  186. $servers[$k]['available_status'] = 0;
  187. } else if ((time() - 300) >= $servers[$k]['last_push_at']) {
  188. $servers[$k]['available_status'] = 1;
  189. } else {
  190. $servers[$k]['available_status'] = 2;
  191. }
  192. }
  193. }
  194. public function getAllServers()
  195. {
  196. $servers = array_merge(
  197. $this->getShadowsocksServers(),
  198. $this->getV2rayServers(),
  199. $this->getTrojanServers()
  200. );
  201. $this->mergeData($servers);
  202. $tmp = array_column($servers, 'sort');
  203. array_multisort($tmp, SORT_ASC, $servers);
  204. return $servers;
  205. }
  206. public function getRoutes(array $routeIds)
  207. {
  208. $routes = ServerRoute::select(['id', 'match', 'action', 'action_value'])->whereIn('id', $routeIds)->get();
  209. // TODO: remove on 1.8.0
  210. foreach ($routes as $k => $route) {
  211. $array = json_decode($route->match, true);
  212. if (is_array($array)) $routes[$k]['match'] = $array;
  213. }
  214. // TODO: remove on 1.8.0
  215. return $routes;
  216. }
  217. public function getServer($serverId, $serverType)
  218. {
  219. switch ($serverType) {
  220. case 'v2ray':
  221. return ServerV2ray::find($serverId);
  222. case 'shadowsocks':
  223. return ServerShadowsocks::find($serverId);
  224. case 'trojan':
  225. return ServerTrojan::find($serverId);
  226. default:
  227. return false;
  228. }
  229. }
  230. }