where('show', 1); } $v2ray = $model->get(); for ($i = 0; $i < count($v2ray); $i++) { $v2ray[$i]['type'] = 'v2ray'; $groupId = $v2ray[$i]['group_id']; if (in_array($user->group_id, $groupId)) { if ($v2ray[$i]['parent_id']) { $v2ray[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $v2ray[$i]['parent_id'])); } else { $v2ray[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $v2ray[$i]['id'])); } array_push($servers, $v2ray[$i]->toArray()); } } return $servers; } public function getTrojan(User $user, $all = false):array { $servers = []; $model = ServerTrojan::orderBy('sort', 'ASC'); if (!$all) { $model->where('show', 1); } $trojan = $model->get(); for ($i = 0; $i < count($trojan); $i++) { $trojan[$i]['type'] = 'trojan'; $groupId = $trojan[$i]['group_id']; if (in_array($user->group_id, $groupId)) { if ($trojan[$i]['parent_id']) { $trojan[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojan[$i]['parent_id'])); } else { $trojan[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojan[$i]['id'])); } array_push($servers, $trojan[$i]->toArray()); } } return $servers; } public function getShadowsocks(User $user, $all = false) { $servers = []; $model = ServerShadowsocks::orderBy('sort', 'ASC'); if (!$all) { $model->where('show', 1); } $shadowsocks = $model->get(); for ($i = 0; $i < count($shadowsocks); $i++) { $shadowsocks[$i]['type'] = 'shadowsocks'; $groupId = $shadowsocks[$i]['group_id']; if (in_array($user->group_id, $groupId)) { if ($shadowsocks[$i]['parent_id']) { $shadowsocks[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $shadowsocks[$i]['parent_id'])); } else { $shadowsocks[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $shadowsocks[$i]['id'])); } array_push($servers, $shadowsocks[$i]->toArray()); } } return $servers; } public function getAvailableServers(User $user, $all = false) { $servers = array_merge( $this->getShadowsocks($user, $all), $this->getV2ray($user, $all), $this->getTrojan($user, $all) ); $tmp = array_column($servers, 'sort'); array_multisort($tmp, SORT_ASC, $servers); return $servers; } public function getAvailableUsers($groupId) { return User::whereIn('group_id', $groupId) ->whereRaw('u + d < transfer_enable') ->where(function ($query) { $query->where('expired_at', '>=', time()) ->orWhere('expired_at', NULL); }) ->where('banned', 0) ->select([ 'id', 'email', 't', 'u', 'd', 'transfer_enable', 'uuid' ]) ->get(); } public function getV2RayConfig(int $nodeId, int $localPort) { $server = Server::find($nodeId); if (!$server) { abort(500, '节点不存在'); } $json = json_decode(self::V2RAY_CONFIG); $json->log->loglevel = (int)config('v2board.server_log_enable') ? 'debug' : 'none'; $json->inboundDetour[0]->port = (int)$localPort; $json->inbound->port = (int)$server->server_port; $json->inbound->streamSettings->network = $server->network; $this->setDns($server, $json); $this->setNetwork($server, $json); $this->setRule($server, $json); $this->setTls($server, $json); return $json; } public function getTrojanConfig(int $nodeId, int $localPort) { $server = ServerTrojan::find($nodeId); if (!$server) { abort(500, '节点不存在'); } $json = json_decode(self::TROJAN_CONFIG); $json->local_port = $server->server_port; $json->ssl->sni = $server->server_name ? $server->server_name : $server->host; $json->ssl->cert = "/root/.cert/server.crt"; $json->ssl->key = "/root/.cert/server.key"; $json->api->api_port = $localPort; return $json; } private function setDns(Server $server, object $json) { if ($server->dnsSettings) { $dns = $server->dnsSettings; if (isset($dns->servers)) { array_push($dns->servers, '1.1.1.1'); array_push($dns->servers, 'localhost'); } $json->dns = $dns; $json->outbound->settings->domainStrategy = 'UseIP'; } } private function setNetwork(Server $server, object $json) { if ($server->networkSettings) { switch ($server->network) { case 'tcp': $json->inbound->streamSettings->tcpSettings = $server->networkSettings; break; case 'kcp': $json->inbound->streamSettings->kcpSettings = $server->networkSettings; break; case 'ws': $json->inbound->streamSettings->wsSettings = $server->networkSettings; break; case 'http': $json->inbound->streamSettings->httpSettings = $server->networkSettings; break; case 'domainsocket': $json->inbound->streamSettings->dsSettings = $server->networkSettings; break; case 'quic': $json->inbound->streamSettings->quicSettings = $server->networkSettings; break; case 'grpc': $json->inbound->streamSettings->grpcSettings = $server->networkSettings; break; } } } private function setRule(Server $server, object $json) { $domainRules = array_filter(explode(PHP_EOL, config('v2board.server_v2ray_domain'))); $protocolRules = array_filter(explode(PHP_EOL, config('v2board.server_v2ray_protocol'))); if ($server->ruleSettings) { $ruleSettings = $server->ruleSettings; // domain if (isset($ruleSettings->domain)) { $ruleSettings->domain = array_filter($ruleSettings->domain); if (!empty($ruleSettings->domain)) { $domainRules = array_merge($domainRules, $ruleSettings->domain); } } // protocol if (isset($ruleSettings->protocol)) { $ruleSettings->protocol = array_filter($ruleSettings->protocol); if (!empty($ruleSettings->protocol)) { $protocolRules = array_merge($protocolRules, $ruleSettings->protocol); } } } if (!empty($domainRules)) { $domainObj = new \StdClass(); $domainObj->type = 'field'; $domainObj->domain = $domainRules; $domainObj->outboundTag = 'block'; array_push($json->routing->rules, $domainObj); } if (!empty($protocolRules)) { $protocolObj = new \StdClass(); $protocolObj->type = 'field'; $protocolObj->protocol = $protocolRules; $protocolObj->outboundTag = 'block'; array_push($json->routing->rules, $protocolObj); } if (empty($domainRules) && empty($protocolRules)) { $json->inbound->sniffing->enabled = false; } } private function setTls(Server $server, object $json) { if ((int)$server->tls) { $tlsSettings = $server->tlsSettings; $json->inbound->streamSettings->security = 'tls'; $tls = (object)[ 'certificateFile' => '/root/.cert/server.crt', 'keyFile' => '/root/.cert/server.key' ]; $json->inbound->streamSettings->tlsSettings = new \StdClass(); if (isset($tlsSettings->serverName)) { $json->inbound->streamSettings->tlsSettings->serverName = (string)$tlsSettings->serverName; } if (isset($tlsSettings->allowInsecure)) { $json->inbound->streamSettings->tlsSettings->allowInsecure = (int)$tlsSettings->allowInsecure ? true : false; } $json->inbound->streamSettings->tlsSettings->certificates[0] = $tls; } } public function log(int $userId, int $serverId, int $u, int $d, float $rate, string $method) { $timestamp = strtotime(date('Y-m-d H:0')); $serverLog = ServerLog::where('log_at', '>=', $timestamp) ->where('log_at', '<', $timestamp + 3600) ->where('server_id', $serverId) ->where('user_id', $userId) ->where('rate', $rate) ->where('method', $method) ->lockForUpdate() ->first(); if ($serverLog) { $serverLog->u = $serverLog->u + $u; $serverLog->d = $serverLog->d + $d; return $serverLog->save(); } else { $serverLog = new ServerLog(); $serverLog->user_id = $userId; $serverLog->server_id = $serverId; $serverLog->u = $u; $serverLog->d = $d; $serverLog->rate = $rate; $serverLog->log_at = $timestamp; $serverLog->method = $method; return $serverLog->save(); } } public function getShadowsocksServers() { $server = ServerShadowsocks::orderBy('sort', 'ASC')->get(); for ($i = 0; $i < count($server); $i++) { $server[$i]['type'] = 'shadowsocks'; } return $server->toArray(); } public function getV2rayServers() { $server = Server::orderBy('sort', 'ASC')->get(); for ($i = 0; $i < count($server); $i++) { $server[$i]['type'] = 'v2ray'; } return $server->toArray(); } public function getTrojanServers() { $server = ServerTrojan::orderBy('sort', 'ASC')->get(); for ($i = 0; $i < count($server); $i++) { $server[$i]['type'] = 'trojan'; } return $server->toArray(); } public function mergeData(&$servers) { foreach ($servers as $k => $v) { $serverType = strtoupper($servers[$k]['type']); $servers[$k]['online'] = Cache::get(CacheKey::get("SERVER_{$serverType}_ONLINE_USER", $servers[$k]['parent_id'] ? $servers[$k]['parent_id'] : $servers[$k]['id'])); if ($servers[$k]['parent_id']) { $servers[$k]['last_check_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_CHECK_AT", $servers[$k]['parent_id'])); $servers[$k]['last_push_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_PUSH_AT", $servers[$k]['parent_id'])); } else { $servers[$k]['last_check_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_CHECK_AT", $servers[$k]['id'])); $servers[$k]['last_push_at'] = Cache::get(CacheKey::get("SERVER_{$serverType}_LAST_PUSH_AT", $servers[$k]['id'])); } if ((time() - 300) >= $servers[$k]['last_check_at']) { $servers[$k]['available_status'] = 0; } else if ((time() - 300) >= $servers[$k]['last_push_at']) { $servers[$k]['available_status'] = 1; } else { $servers[$k]['available_status'] = 2; } } } public function getAllServers() { $servers = array_merge( $this->getShadowsocksServers(), $this->getV2rayServers(), $this->getTrojanServers() ); $this->mergeData($servers); $tmp = array_column($servers, 'sort'); array_multisort($tmp, SORT_ASC, $servers); return $servers; } }