├── .editorconfig ├── .gitignore ├── App ├── HttpController │ ├── Links.php │ └── Router.php ├── Models │ ├── Link.php │ ├── Models.php │ ├── Node.php │ ├── Relay.php │ └── User.php └── Utils │ ├── AppURI.php │ ├── Conf.php │ ├── Subcribe.php │ └── Tools.php ├── EasySwooleEvent.php ├── Log ├── log_DEBUG.log └── swoole.log ├── README.md ├── Resources └── Conf │ ├── clash │ └── default.tpl │ ├── quantumult │ └── quantumult.tpl │ ├── surfboard │ └── default.tpl │ ├── surge │ └── default.tpl │ └── surge2 │ └── default.tpl ├── Temp └── pid.pid ├── appprofile.example.php ├── composer.json ├── composer.lock ├── config.php └── easyswoole /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | end_of_line = lf 3 | indent_style = space 4 | insert_final_newline = true 5 | trim_trailing_whitespace = true 6 | charset = utf-8 7 | 8 | [*.{yml,yaml}] 9 | indent_size = 2 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vs/ 3 | .vscode/ 4 | */.DS_Store 5 | .DS_Store 6 | .php_cs.cache 7 | vendor 8 | 9 | php_errors.log 10 | composer.phar 11 | 12 | dev.php 13 | produce.php 14 | appprofile.php 15 | 16 | -------------------------------------------------------------------------------- /App/HttpController/Links.php: -------------------------------------------------------------------------------- 1 | where('token', $this->request()->getQueryParam('token'))->first(); 17 | if ($sToken === null) { 18 | // token 不存在 19 | return $this->response() 20 | ->withStatus(404) 21 | ->write('not found.'); 22 | } 23 | 24 | // 取得 token 对应用户 25 | $user = $sToken->getUser(); 26 | if ($user === null) { 27 | // 用户不存在 28 | // 删除该 token 记录 29 | $sToken->delete(); 30 | return $this->response() 31 | ->withStatus(404) 32 | ->write('not found user.'); 33 | } 34 | 35 | // 配置 36 | $config = Config::getInstance(); 37 | 38 | // 筛选节点的类型 39 | $Rule['type'] = $this->requestQuery('type', 'all'); 40 | 41 | // 合并订阅以及单端口 42 | $Rule['is_mu'] = (int) $this->requestQuery('mu', $config->getConf('SUB.mergeSub')); 43 | 44 | // 获取指定等级的节点 45 | if ($this->requestFilled('class')) { 46 | $class = trim(urldecode($this->requestQuery('class'))); 47 | $Rule['content']['class'] = array_map( 48 | function ($item) { 49 | return (int) $item; 50 | }, 51 | explode('-', $class) 52 | ); 53 | } 54 | 55 | // 去除指定等级的节点 56 | if ($this->requestFilled('noclass')) { 57 | $noclass = trim(urldecode($this->requestQuery('noclass'))); 58 | $Rule['content']['noclass'] = array_map( 59 | function ($item) { 60 | return (int) $item; 61 | }, 62 | explode('-', $noclass) 63 | ); 64 | } 65 | 66 | // 使用正则对节点名称进行筛选 67 | if ($this->requestFilled('regex')) { 68 | $Rule['content']['regex'] = trim(urldecode($this->requestQuery('regex'))); 69 | } 70 | 71 | // 为节点名称添加 Emoji 72 | $Rule['emoji'] = (bool) $this->requestQuery('emoji', $config->getConf('SUB.addEmoji')); 73 | 74 | // 控制订阅中显示流量以及到期时间等 75 | $Rule['extend'] = (bool) $this->requestQuery('extend', $config->getConf('SUB.extend')); 76 | 77 | // 当前访问 URL 78 | $Rule['URL'] = $config->getConf('baseUrl') . $this->request()->getServerParams()['request_uri'] . '?'. $this->request()->getServerParams()['query_string']; 79 | 80 | // 订阅类型 81 | $subscribe_type = ''; 82 | 83 | $opts = $this->request()->getQueryParams(); 84 | 85 | $sub_type_array = ['list', 'ssd', 'clash', 'surge', 'surfboard', 'quantumult', 'quantumultx', 'sub']; 86 | foreach ($sub_type_array as $key) { 87 | if (isset($opts[$key])) { 88 | $query_value = $opts[$key]; 89 | if ($query_value != '0' && $query_value != '') { 90 | 91 | // 兼容代码开始 92 | if ($key == 'sub' && $query_value > 4) { 93 | $query_value = 1; 94 | } 95 | // 兼容代码结束 96 | 97 | if ($key == 'list') { 98 | $SubscribeExtend = $this->getSubscribeExtend($query_value); 99 | } else { 100 | $SubscribeExtend = $this->getSubscribeExtend($key, $query_value); 101 | } 102 | $filename = $SubscribeExtend['filename'] . '_' . time() . '.' . $SubscribeExtend['suffix']; 103 | $subscribe_type = $SubscribeExtend['filename']; 104 | 105 | $class = ('get' . $SubscribeExtend['class']); 106 | $content = Subcribe::$class($user, $query_value, $opts, $Rule); 107 | break; 108 | } 109 | continue; 110 | } 111 | } 112 | 113 | $this->response()->withHeader('Content-type', ' application/octet-stream; charset=utf-8'); 114 | $this->response()->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate'); 115 | $this->response()->withHeader('Content-Disposition', ' attachment; filename=' . $filename); 116 | $this->response()->withHeader( 117 | 'Subscription-Userinfo', 118 | (' upload=' . $user->u 119 | . '; download=' . $user->d 120 | . '; total=' . $user->transfer_enable 121 | . '; expire=' . strtotime($user->class_expire)) 122 | ); 123 | $this->response()->write($content); 124 | 125 | // 记录订阅日志 126 | if ($config->getConf('SUB.Log') === true) { 127 | $user->addSubLog($subscribe_type, $this->getRemoteIP(), $this->request()->getHeader('user-agent')); 128 | } 129 | 130 | return $this->response()->end(); 131 | } 132 | 133 | /** 134 | * 获取订阅类型的文件名 135 | * 136 | * @param string $type 订阅类型 137 | * @param string $value 138 | */ 139 | public function getSubscribeExtend(string $type, string $value = null): array 140 | { 141 | switch ($type) { 142 | case 'ss': 143 | $return = [ 144 | 'filename' => 'SS', 145 | 'suffix' => 'txt', 146 | 'class' => 'Sub' 147 | ]; 148 | break; 149 | case 'ssa': 150 | $return = [ 151 | 'filename' => 'SSA', 152 | 'suffix' => 'json', 153 | 'class' => 'Lists' 154 | ]; 155 | break; 156 | case 'ssd': 157 | $return = [ 158 | 'filename' => 'SSD', 159 | 'suffix' => 'txt', 160 | 'class' => 'SSD' 161 | ]; 162 | break; 163 | case 'ssr': 164 | $return = [ 165 | 'filename' => 'SSR', 166 | 'suffix' => 'txt', 167 | 'class' => 'Sub' 168 | ]; 169 | break; 170 | case 'sub': 171 | $strArray = [ 172 | 1 => 'ssr', 173 | 2 => 'ss', 174 | 3 => 'v2rayn', 175 | 4 => 'trojan', 176 | ]; 177 | $str = (!in_array($value, $strArray) ? $strArray[$value] : $strArray[1]); 178 | $return = self::getSubscribeExtend($str); 179 | break; 180 | case 'clash': 181 | if ($value !== null) { 182 | if ((int) $value == 2) { 183 | $return = self::getSubscribeExtend('clashr'); 184 | $return['class'] = 'Clash'; 185 | } else { 186 | $return = self::getSubscribeExtend('clash'); 187 | $return['class'] = 'Clash'; 188 | } 189 | } else { 190 | $return = [ 191 | 'filename' => 'Clash', 192 | 'suffix' => 'yaml', 193 | 'class' => 'Lists' 194 | ]; 195 | } 196 | break; 197 | case 'surge': 198 | if ($value !== null) { 199 | $return = [ 200 | 'filename' => 'Surge', 201 | 'suffix' => 'conf', 202 | 'class' => 'Surge' 203 | ]; 204 | $return['filename'] .= $value; 205 | } else { 206 | $return = [ 207 | 'filename' => 'SurgeList', 208 | 'suffix' => 'list', 209 | 'class' => 'Lists' 210 | ]; 211 | } 212 | break; 213 | case 'clashr': 214 | $return = [ 215 | 'filename' => 'ClashR', 216 | 'suffix' => 'yaml', 217 | 'class' => 'Lists' 218 | ]; 219 | break; 220 | case 'v2rayn': 221 | $return = [ 222 | 'filename' => 'V2RayN', 223 | 'suffix' => 'txt', 224 | 'class' => 'Sub' 225 | ]; 226 | break; 227 | case 'kitsunebi': 228 | $return = [ 229 | 'filename' => 'Kitsunebi', 230 | 'suffix' => 'txt', 231 | 'class' => 'Lists' 232 | ]; 233 | break; 234 | case 'surfboard': 235 | $return = [ 236 | 'filename' => 'Surfboard', 237 | 'suffix' => 'conf', 238 | 'class' => 'Surfboard' 239 | ]; 240 | break; 241 | case 'quantumult': 242 | if ($value !== null) { 243 | if ((int) $value == 2) { 244 | $return = self::getSubscribeExtend('quantumult_sub'); 245 | } else { 246 | $return = self::getSubscribeExtend('quantumult_conf'); 247 | } 248 | } else { 249 | $return = [ 250 | 'filename' => 'Quantumult', 251 | 'suffix' => 'conf', 252 | 'class' => 'Lists' 253 | ]; 254 | } 255 | break; 256 | case 'quantumultx': 257 | $return = [ 258 | 'filename' => 'QuantumultX', 259 | 'suffix' => 'txt', 260 | 'class' => 'Lists' 261 | ]; 262 | if ($value !== null) { 263 | $return['class'] = 'QuantumultX'; 264 | } 265 | break; 266 | case 'shadowrocket': 267 | $return = [ 268 | 'filename' => 'Shadowrocket', 269 | 'suffix' => 'txt', 270 | 'class' => 'Lists' 271 | ]; 272 | break; 273 | case 'clash_provider': 274 | $return = [ 275 | 'filename' => 'ClashProvider', 276 | 'suffix' => 'yaml', 277 | 'class' => 'Lists' 278 | ]; 279 | break; 280 | case 'clashr_provider': 281 | $return = [ 282 | 'filename' => 'ClashRProvider', 283 | 'suffix' => 'yaml', 284 | 'class' => 'Lists' 285 | ]; 286 | break; 287 | case 'quantumult_sub': 288 | $return = [ 289 | 'filename' => 'QuantumultSub', 290 | 'suffix' => 'conf', 291 | 'class' => 'Quantumult' 292 | ]; 293 | break; 294 | case 'quantumult_conf': 295 | $return = [ 296 | 'filename' => 'QuantumultConf', 297 | 'suffix' => 'conf', 298 | 'class' => 'Quantumult' 299 | ]; 300 | break; 301 | default: 302 | $return = [ 303 | 'filename' => 'UndefinedNode', 304 | 'suffix' => 'txt', 305 | 'class' => 'Sub' 306 | ]; 307 | break; 308 | } 309 | return $return; 310 | } 311 | 312 | /** 313 | * 判断查询字符串是否存在且不为空 314 | * 315 | * @param mixed $key 316 | */ 317 | public function requestFilled($key): bool 318 | { 319 | $params = $this->request()->getQueryParams(); 320 | $keys = is_array($key) ? $key : func_get_args(); 321 | foreach ($keys as $value) { 322 | if (!isset($params[$value])) { 323 | return false; 324 | } 325 | if ($params[$value] == '') { 326 | return false; 327 | } 328 | } 329 | return true; 330 | } 331 | 332 | /** 333 | * 获取查询字符串或返回默认值 334 | * 335 | * @param string $key 336 | * @param mixed $default 337 | */ 338 | public function requestQuery(string $key, $default = null) 339 | { 340 | if (isset($this->request()->getQueryParams()[$key])) { 341 | return $this->request()->getQueryParams()[$key]; 342 | } 343 | if ($default !== null) { 344 | return $default; 345 | } 346 | return null; 347 | } 348 | 349 | /** 350 | * 取得客户端 IP 351 | */ 352 | public function getRemoteIP(): string 353 | { 354 | $info = ServerManager::getInstance() 355 | ->getSwooleServer() 356 | ->connection_info( 357 | $this->request()->getSwooleRequest()->fd 358 | ); 359 | return $info['remote_ip']; 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /App/HttpController/Router.php: -------------------------------------------------------------------------------- 1 | setGlobalMode(true); 15 | 16 | $routeCollector->get('/', function (Request $request, Response $response) { 17 | $response->write('
geekSubcribeX backend
'); 18 | return false; 19 | }); 20 | 21 | $routeCollector->get('/link/{token}', '/Links'); 22 | 23 | $this->setRouterNotFoundCallBack(function (Request $request, Response $response) { 24 | $response->withStatus(404); 25 | $response->write('
404 not found
'); 26 | return false; 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /App/Models/Link.php: -------------------------------------------------------------------------------- 1 | userid); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /App/Models/Models.php: -------------------------------------------------------------------------------- 1 | 'float', 19 | 'traffic_rate' => 'float', 20 | 'mu_only' => 'int', 21 | 'sort' => 'int', 22 | ]; 23 | 24 | /** 25 | * 获取节点出口地址 26 | */ 27 | public function getServer(): string 28 | { 29 | $out = ''; 30 | $explode = explode(';', $this->server); 31 | if (in_array($this->sort, [0, 10]) && isset($explode[1]) && stripos($explode[1], 'server=') !== false) { 32 | $out = Tools::parse_args($explode[1])['server']; 33 | } 34 | return ($out != '' ? $out : $explode[0]); 35 | } 36 | 37 | /** 38 | * 获取 SS/SSR 节点 39 | * 40 | * @param User $user 41 | * @param int $mu_port 42 | * @param int $relay_rule_id 43 | * @param int $is_ss 44 | * @param bool $emoji 45 | */ 46 | public function getItem(User $user, int $mu_port = 0, int $relay_rule_id = 0, int $is_ss = 0, bool $emoji = false):? array 47 | { 48 | $relay_rule = Relay::where('id', $relay_rule_id) 49 | ->where( 50 | static function ($query) use ($user) { 51 | $query->Where('user_id', '=', $user->id) 52 | ->orWhere('user_id', '=', 0); 53 | } 54 | ) 55 | ->orderBy('priority', 'DESC') 56 | ->orderBy('id') 57 | ->first(); 58 | $node_name = $this->name; 59 | if ($relay_rule != null) { 60 | $node_name .= ' - ' . $relay_rule->dist_node()->name; 61 | } 62 | if ($mu_port != 0) { 63 | $mu_user = User::where('port', '=', $mu_port)->where('is_multi_user', '<>', 0)->first(); 64 | if ($mu_user == null) { 65 | return null; 66 | } 67 | $mu_user->obfs_param = $user->getMuMd5(); 68 | $mu_user->protocol_param = $user->id . ':' . $user->passwd; 69 | $user = $mu_user; 70 | $node_name .= (Config::getInstance()->getConf('SUB.disable_sub_mu_port') ? '' : ' - ' . $mu_port . ' 单端口'); 71 | } 72 | if ($is_ss) { 73 | if (!Tools::SSCanConnect($user)) { 74 | return null; 75 | } 76 | $user = Tools::getSSConnectInfo($user); 77 | $return_array['type'] = 'ss'; 78 | } else { 79 | if (!Tools::SSRCanConnect($user)) { 80 | return null; 81 | } 82 | $user = Tools::getSSRConnectInfo($user); 83 | $return_array['type'] = 'ssr'; 84 | } 85 | $return_array['address'] = $this->getServer(); 86 | $return_array['port'] = $user->port; 87 | $return_array['protocol'] = $user->protocol; 88 | $return_array['protocol_param'] = $user->protocol_param; 89 | $return_array['obfs'] = $user->obfs; 90 | $return_array['obfs_param'] = $user->obfs_param; 91 | if ($mu_port != 0 && strpos($this->server, ';') !== false) { 92 | $node_tmp = Tools::OutPort($this->server, $this->name, $mu_port); 93 | $return_array['port'] = $node_tmp['port']; 94 | $node_name = $node_tmp['name']; 95 | } 96 | $return_array['passwd'] = $user->passwd; 97 | $return_array['method'] = $user->method; 98 | $return_array['remark'] = ($emoji ? Tools::addEmoji($node_name) : $node_name); 99 | $return_array['class'] = $this->node_class; 100 | $return_array['group'] = Config::getInstance()->getConf('appName'); 101 | $return_array['ratio'] = ($relay_rule != null ? $this->traffic_rate + $relay_rule->dist_node()->traffic_rate : $this->traffic_rate); 102 | 103 | return $return_array; 104 | } 105 | 106 | /** 107 | * 获取 V2Ray 节点 108 | * 109 | * @param User $user 110 | * @param int $mu_port 111 | * @param int $relay_rule_id 112 | * @param int $is_ss 113 | * @param bool $emoji 114 | */ 115 | public function getV2RayItem(User $user, int $mu_port = 0, int $relay_rule_id = 0, int $is_ss = 0, bool $emoji = false): array 116 | { 117 | $item = Tools::v2Array($this->server); 118 | $item['type'] = 'vmess'; 119 | $item['remark'] = ($emoji ? Tools::addEmoji($this->name) : $this->name); 120 | $item['id'] = $user->getUuid(); 121 | $item['class'] = $this->node_class; 122 | return $item; 123 | } 124 | 125 | /** 126 | * 获取 V2RayPlugin | obfs 节点 127 | * 128 | * @param User $user 用户 129 | * @param int $mu_port 130 | * @param int $relay_rule_id 131 | * @param int $is_ss 132 | * @param bool $emoji 133 | * 134 | * @return array|null 135 | */ 136 | public function getV2RayPluginItem(User $user, int $mu_port = 0, int $relay_rule_id = 0, int $is_ss = 0, bool $emoji = false) 137 | { 138 | $return_array = Tools::ssv2Array($this->server); 139 | // 非 AEAD 加密无法使用 140 | if ($return_array['net'] != 'obfs' && !in_array($user->method, Tools::getSupportParam('ss_aead_method'))) { 141 | return null; 142 | } 143 | $return_array['remark'] = ($emoji ? Tools::addEmoji($this->name) : $this->name); 144 | $return_array['address'] = $return_array['add']; 145 | $return_array['method'] = $user->method; 146 | $return_array['passwd'] = $user->passwd; 147 | $return_array['protocol'] = 'origin'; 148 | $return_array['protocol_param'] = ''; 149 | if ($return_array['net'] == 'obfs') { 150 | $return_array['obfs_param'] = $user->getMuMd5(); 151 | } else { 152 | $return_array['obfs'] = 'v2ray'; 153 | if ($return_array['tls'] == 'tls' && $return_array['net'] == 'ws') { 154 | $return_array['obfs_param'] = ('mode=ws;security=tls;path=' . $return_array['path'] . 155 | ';host=' . $return_array['host']); 156 | } else { 157 | $return_array['obfs_param'] = ('mode=ws;security=none;path=' . $return_array['path'] . 158 | ';host=' . $return_array['host']); 159 | } 160 | $return_array['path'] = ($return_array['path'] . '?redirect=' . $user->getMuMd5()); 161 | } 162 | $return_array['class'] = $this->node_class; 163 | $return_array['group'] = Config::getInstance()->getConf('appName'); 164 | $return_array['type'] = 'ss'; 165 | $return_array['ratio'] = $this->traffic_rate; 166 | 167 | return $return_array; 168 | } 169 | 170 | /** 171 | * Trojan 节点 172 | * 173 | * @param User $user 用户 174 | * @param int $mu_port 175 | * @param int $relay_rule_id 176 | * @param int $is_ss 177 | * @param bool $emoji 178 | */ 179 | public function getTrojanItem(User $user, int $mu_port = 0, int $relay_rule_id = 0, int $is_ss = 0, bool $emoji = false): array 180 | { 181 | $server = explode(';', $this->server); 182 | $opt = []; 183 | if (isset($server[1])) { 184 | $opt = Tools::parse_args($server[1]); 185 | } 186 | $item['remark'] = ($emoji ? Tools::addEmoji($this->name) : $this->name); 187 | $item['type'] = 'trojan'; 188 | $item['address'] = $server[0]; 189 | $item['port'] = (isset($opt['port']) ? (int) $opt['port'] : 443); 190 | $item['passwd'] = $user->getUuid(); 191 | $item['host'] = $item['address']; 192 | if (isset($opt['host'])) { 193 | $item['host'] = $opt['address']; 194 | } 195 | return $item; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /App/Models/Relay.php: -------------------------------------------------------------------------------- 1 | attributes['user_id'])->first(); 15 | if ($user == null) { 16 | self::where('id', '=', $this->attributes['id'])->delete(); 17 | return null; 18 | } 19 | 20 | return $user; 21 | } 22 | 23 | public function Source_Node() 24 | { 25 | $node = Node::where('id', $this->attributes['source_node_id'])->first(); 26 | if ($node == null && $this->attributes['source_node_id'] != 0) { 27 | self::where('id', '=', $this->attributes['id'])->delete(); 28 | return null; 29 | } 30 | 31 | return $node; 32 | } 33 | 34 | public function Dist_Node() 35 | { 36 | if ($this->attributes['dist_node_id'] == -1) { 37 | return null; 38 | } 39 | 40 | $node = Node::where('id', $this->attributes['dist_node_id'])->first(); 41 | if ($node == null) { 42 | self::where('id', '=', $this->attributes['id'])->delete(); 43 | return null; 44 | } 45 | 46 | return $node; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /App/Models/User.php: -------------------------------------------------------------------------------- 1 | 'float', 26 | 'u' => 'float', 27 | 'd' => 'float', 28 | 'port' => 'int', 29 | 'transfer_enable' => 'float', 30 | 'enable' => 'int', 31 | 'is_admin' => 'boolean', 32 | 'is_multi_user' => 'int', 33 | 'node_speedlimit' => 'float', 34 | 'sendDailyMail' => 'int' 35 | ]; 36 | 37 | public function getUuid() 38 | { 39 | return Uuid::uuid3( 40 | Uuid::NAMESPACE_DNS, 41 | $this->attributes['id'] . '|' . $this->attributes['passwd'] 42 | )->toString(); 43 | } 44 | 45 | public function getMuMd5() 46 | { 47 | $str = str_replace( 48 | array('%id', '%suffix'), 49 | array($this->attributes['id'], Config::getInstance()->getConf('mu_suffix')), 50 | Config::getInstance()->getConf('mu_regex') 51 | ); 52 | preg_match_all("|%-?[1-9]\d*m|U", $str, $matches, PREG_PATTERN_ORDER); 53 | foreach ($matches[0] as $key) { 54 | $key_match = str_replace(array('%', 'm'), '', $key); 55 | $md5 = substr( 56 | MD5($this->attributes['id'] . $this->attributes['passwd'] . $this->attributes['method'] . $this->attributes['obfs'] . $this->attributes['protocol']), 57 | ($key_match < 0 ? $key_match : 0), 58 | abs($key_match) 59 | ); 60 | $str = str_replace($key, $md5, $str); 61 | } 62 | return $str; 63 | } 64 | 65 | /* 66 | * 剩余流量 67 | */ 68 | public function unusedTraffic() 69 | { 70 | $total = $this->attributes['u'] + $this->attributes['d']; 71 | $transfer_enable = $this->attributes['transfer_enable']; 72 | return Tools::flowAutoShow($transfer_enable - $total); 73 | } 74 | 75 | /** 76 | * 获取全部节点对象 77 | * 78 | * @param mixed $sort 数值或数组 79 | * @param array $rules 节点筛选规则 80 | */ 81 | public function getNodes($sort, array $rules = []): \Illuminate\Database\Eloquent\Collection 82 | { 83 | $query = Node::query(); 84 | if (is_array($sort)) { 85 | $query->whereIn('sort', $sort); 86 | } else { 87 | $query->where('sort', $sort); 88 | } 89 | if (!$this->is_admin) { 90 | $group = ($this->node_group != 0 ? [0, $this->node_group] : [0]); 91 | $query->whereIn('node_group', $group) 92 | ->where('node_class', '<=', $this->class); 93 | } 94 | // 等级筛选 95 | if (isset($rules['content']['class']) && count($rules['content']['class']) > 0) { 96 | $query->whereIn('node_class', $rules['content']['class']); 97 | } 98 | if (isset($rules['content']['noclass']) && count($rules['content']['noclass']) > 0) { 99 | $query->whereNotIn('node_class', $rules['content']['noclass']); 100 | } 101 | // 等级筛选 end 102 | $nodes = $query->where('type', '1') 103 | ->orderBy('name')->get(); 104 | 105 | return $nodes; 106 | } 107 | 108 | /** 109 | * 获取全部节点 110 | * 111 | * ``` 112 | * $Rule = [ 113 | * 'type' => 'all | ss | ssr | vmess | trojan', 114 | * 'emoji' => false, 115 | * 'is_mu' => 1, 116 | * 'content' => [ 117 | * 'noclass' => [0, 1, 2], 118 | * 'class' => [0, 1, 2], 119 | * 'regex' => '.*香港.*HKBN.*', 120 | * ] 121 | * ] 122 | * ``` 123 | * 124 | * @param array $Rule 节点筛选规则 125 | */ 126 | public function getNew_AllItems(array $Rule): array 127 | { 128 | $is_ss = [0]; 129 | $is_mu = (isset($Rule['is_mu']) ? $Rule['is_mu'] : (int) Config::getInstance()->getConf('SUB.mergeSub')); 130 | $emoji = (isset($Rule['emoji']) ? $Rule['emoji'] : false); 131 | 132 | switch ($Rule['type']) { 133 | case 'ss': 134 | $sort = [0, 10, 13]; 135 | $is_ss = [1]; 136 | break; 137 | case 'ssr': 138 | $sort = [0, 10]; 139 | break; 140 | case 'vmess': 141 | $sort = [11, 12]; 142 | break; 143 | case 'trojan': 144 | $sort = [14]; 145 | break; 146 | default: 147 | $Rule['type'] = 'all'; 148 | $sort = [0, 10, 11, 12, 13, 14]; 149 | $is_ss = [0, 1]; 150 | break; 151 | } 152 | 153 | // 获取节点 154 | $nodes = $this->getNodes($sort, $Rule); 155 | 156 | // 单端口 sort = 9 157 | $mu_nodes = []; 158 | if ($is_mu != 0 && in_array($Rule['type'], ['all', 'ss', 'ssr'])) { 159 | $mu_node_query = Node::query(); 160 | $mu_node_query->where('sort', 9)->where('type', '1'); 161 | if ($is_mu != 1) { 162 | $mu_node_query->where('server', $is_mu); 163 | } 164 | if (!$this->is_admin) { 165 | $group = ($this->node_group != 0 ? [0, $this->node_group] : [0]); 166 | $mu_node_query->where('node_class', '<=', $this->class) 167 | ->whereIn('node_group', $group); 168 | } 169 | $mu_nodes = $mu_node_query->get(); 170 | } 171 | 172 | // 获取适用于用户的中转规则 173 | $relay_rules = $this->getRelays(); 174 | 175 | $return_array = []; 176 | foreach ($nodes as $node) { 177 | if (isset($Rule['content']['regex']) && $Rule['content']['regex'] != '') { 178 | // 节点名称筛选 179 | if ( 180 | Conf::getMatchProxy( 181 | [ 182 | 'remark' => $node->name 183 | ], 184 | [ 185 | 'content' => [ 186 | 'regex' => $Rule['content']['regex'] 187 | ] 188 | ] 189 | ) === null 190 | ) { 191 | continue; 192 | } 193 | } 194 | // 筛选 End 195 | 196 | // 其他类型单端口节点 197 | if (in_array($node->sort, [11, 12, 13, 14])) { 198 | $node_class = [ 199 | 11 => 'getV2RayItem', // V2Ray 200 | 12 => 'getV2RayItem', // V2Ray 201 | 13 => 'getV2RayPluginItem', // Rico SS (V2RayPlugin && obfs) 202 | 14 => 'getTrojanItem', // Trojan 203 | ]; 204 | $class = $node_class[$node->sort]; 205 | $item = $node->$class($this, 0, 0, 0, $emoji); 206 | if ($item != null) { 207 | $return_array[] = $item; 208 | } 209 | continue; 210 | } 211 | // 其他类型单端口节点 End 212 | 213 | // SS 节点 214 | if (in_array($node->sort, [0, 10])) { 215 | // 节点非只启用单端口 && 只获取普通端口 216 | if ($node->mu_only != 1 && ($is_mu == 0 || ($is_mu != 0 && Config::getInstance()->getConf('SUB.mergeSub') === true))) { 217 | foreach ($is_ss as $ss) { 218 | if ($node->sort == 10) { 219 | // SS 中转 220 | $relay_rule_id = 0; 221 | $relay_rule = Tools::pick_out_relay_rule($node->id, $this->port, $relay_rules); 222 | if ($relay_rule != null && $relay_rule->dist_node() != null) { 223 | $relay_rule_id = $relay_rule->id; 224 | } 225 | $item = $node->getItem($this, 0, $relay_rule_id, $ss, $emoji); 226 | } else { 227 | // SS 非中转 228 | $item = $node->getItem($this, 0, 0, $ss, $emoji); 229 | } 230 | if ($item != null) { 231 | $return_array[] = $item; 232 | } 233 | } 234 | } 235 | // 获取 SS 普通端口 End 236 | 237 | // 非只启用普通端口 && 获取单端口 238 | if ($node->mu_only != -1 && $is_mu != 0) { 239 | foreach ($is_ss as $ss) { 240 | foreach ($mu_nodes as $mu_node) { 241 | if ($node->sort == 10) { 242 | // SS 中转 243 | $relay_rule_id = 0; 244 | $relay_rule = Tools::pick_out_relay_rule($node->id, $mu_node->server, $relay_rules); 245 | if ($relay_rule != null && $relay_rule->dist_node() != null) { 246 | $relay_rule_id = $relay_rule->id; 247 | } 248 | $item = $node->getItem($this, $mu_node->server, $relay_rule_id, $ss, $emoji); 249 | } else { 250 | // SS 非中转 251 | $item = $node->getItem($this, $mu_node->server, 0, $ss, $emoji); 252 | } 253 | if ($item != null) { 254 | $return_array[] = $item; 255 | } 256 | } 257 | } 258 | } 259 | // 获取 SS 单端口 End 260 | } 261 | // SS 节点 End 262 | } 263 | 264 | return $return_array; 265 | } 266 | 267 | /** 268 | * 获取全部节点 Url 269 | * 270 | * ``` 271 | * $Rule = [ 272 | * 'type' => 'ss | ssr | vmess', 273 | * 'emoji' => false, 274 | * 'is_mu' => 1, 275 | * 'content' => [ 276 | * 'noclass' => [0, 1, 2], 277 | * 'class' => [0, 1, 2], 278 | * 'regex' => '.*香港.*HKBN.*', 279 | * ] 280 | * ] 281 | * ``` 282 | * 283 | * @param array $Rule 节点筛选规则 284 | */ 285 | public function get_NewAllUrl(array $Rule): string 286 | { 287 | $return_url = ''; 288 | if (strtotime($this->expire_in) < time()) { 289 | return $return_url; 290 | } 291 | $items = $this->getNew_AllItems($Rule); 292 | foreach ($items as $item) { 293 | if ($item['type'] == 'vmess') { 294 | $out = Subcribe::getListItem($item, 'v2rayn'); 295 | } else { 296 | $out = Subcribe::getListItem($item, $Rule['type']); 297 | } 298 | if ($out !== null) { 299 | $return_url .= $out . PHP_EOL; 300 | } 301 | } 302 | return $return_url; 303 | } 304 | 305 | /** 306 | * 获取订阅链接 Token 307 | */ 308 | public function getSubToken():? string 309 | { 310 | $Elink = Link::where('type', 11)->where('userid', $this->id)->first(); 311 | return ($Elink != null ? $Elink->token : null); 312 | } 313 | 314 | /** 315 | * 添加订阅记录 316 | * 317 | * @param string $type 318 | * @param string $ip 319 | * @param string $ua 320 | */ 321 | public function addSubLog($type, $ip, $ua): void 322 | { 323 | Manager::table('user_subscribe_log') 324 | ->insert( 325 | [ 326 | 'user_name' => $this->user_name, 327 | 'user_id' => $this->id, 328 | 'email' => $this->email, 329 | 'subscribe_type' => $type, 330 | 'request_ip' => $ip, 331 | 'request_time' => date('Y-m-d H:i:s'), 332 | 'request_user_agent' => (new AntiXSS())->xss_clean($ua) 333 | ] 334 | ); 335 | } 336 | 337 | /** 338 | * 获取转发规则 339 | */ 340 | public function getRelays() 341 | { 342 | return (!Tools::is_protocol_relay($this) 343 | ? [] 344 | : Relay::where('user_id', $this->id)->orwhere('user_id', 0)->orderBy('id', 'asc')->get()); 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /App/Utils/AppURI.php: -------------------------------------------------------------------------------- 1 | getConf('SUB.add_appName_to_ss_uri') === true 26 | ? '#' . rawurlencode(Config::getInstance()->getConf('appName') . ' - ' . $item['remark']) 27 | : '#' . rawurlencode($item['remark'])); 28 | } else { 29 | $personal_info = $item['method'] . ':' . $item['passwd']; 30 | $ssurl = 'ss://' . Tools::base64_url_encode($personal_info) . '@' . $item['address'] . ':' . $item['port']; 31 | $plugin = ''; 32 | if ($item['obfs'] == 'v2ray' || in_array($item['obfs'], $ss_obfs_list)) { 33 | if (strpos($item['obfs'], 'http') !== false) { 34 | $plugin .= 'obfs-local;obfs=http'; 35 | } elseif (strpos($item['obfs'], 'tls') !== false) { 36 | $plugin .= 'obfs-local;obfs=tls'; 37 | } else { 38 | $plugin .= 'v2ray;' . $item['obfs_param']; 39 | } 40 | if ($item['obfs_param'] != '' && $item['obfs'] != 'v2ray') { 41 | $plugin .= ';obfs-host=' . $item['obfs_param']; 42 | } 43 | $ssurl .= '/?plugin=' . rawurlencode($plugin) . '&group=' . Tools::base64_url_encode(Config::getInstance()->getConf('appName')); 44 | } else { 45 | $ssurl .= '/?group=' . Tools::base64_url_encode(Config::getInstance()->getConf('appName')); 46 | } 47 | $ssurl .= (Config::getInstance()->getConf('SUB.add_appName_to_ss_uri') === true 48 | ? '#' . rawurlencode(Config::getInstance()->getConf('appName') . ' - ' . $item['remark']) 49 | : '#' . rawurlencode($item['remark'])); 50 | } 51 | return $ssurl; 52 | } 53 | 54 | public static function getV2RayNURI(array $item) 55 | { 56 | $return = null; 57 | switch ($item['type']) { 58 | case 'vmess': 59 | $node = [ 60 | 'v' => 2, 61 | 'ps' => $item['remark'], 62 | 'add' => $item['add'], 63 | 'port' => $item['port'], 64 | 'id' => $item['id'], 65 | 'aid' => $item['aid'], 66 | 'net' => $item['net'], 67 | 'type' => $item['headerType'], 68 | 'host' => $item['host'], 69 | 'path' => $item['path'], 70 | 'tls' => $item['tls'] 71 | ]; 72 | $return = ('vmess://' . base64_encode( 73 | json_encode($node, 320) 74 | )); 75 | break; 76 | } 77 | return $return; 78 | } 79 | 80 | public static function getSurgeURI(array $item, int $version) 81 | { 82 | $return = null; 83 | switch ($version) { 84 | case 2: 85 | if ($item['obfs'] == 'v2ray') { 86 | break; 87 | } 88 | if ($item['type'] == 'ss') { 89 | $return = ($item['remark'] . ' = custom, ' . $item['address'] . ', ' . $item['port'] . ', ' . $item['method'] . ', ' . $item['passwd'] . ', https://raw.githubusercontent.com/lhie1/Rules/master/SSEncrypt.module' . self::getSurgeObfs($item)); 90 | } 91 | break; 92 | default: 93 | switch ($item['type']) { 94 | case 'ss': 95 | if ($item['obfs'] == 'v2ray') { 96 | break; 97 | } 98 | $return = ($item['remark'] . ' = ss, ' . $item['address'] . ', ' . $item['port'] . ', encrypt-method=' . $item['method'] . ', password=' . $item['passwd'] . self::getSurgeObfs($item) . ', udp-relay=true'); 99 | break; 100 | case 'vmess': 101 | if (!in_array($item['net'], ['ws', 'tcp'])) { 102 | break; 103 | } 104 | $tls = ($item['tls'] == 'tls' 105 | ? ', tls=true' 106 | : ''); 107 | $ws = ($item['net'] == 'ws' 108 | ? ', ws=true, ws-path=' . $item['path'] . ', ws-headers=host:' . $item['host'] 109 | : ''); 110 | $return = $item['remark'] . ' = vmess, ' . $item['add'] . ', ' . $item['port'] . ', username = ' . $item['id'] . $ws . $tls; 111 | break; 112 | case 'trojan': 113 | $return = ($item['remark'] . ' = trojan, ' . $item['address'] . ', ' . $item['port'] . ', password=' . $item['passwd']); 114 | break; 115 | } 116 | break; 117 | } 118 | return $return; 119 | } 120 | 121 | public static function getSurgeObfs(array $item): string 122 | { 123 | $ss_obfs_list = Tools::getSupportParam('ss_obfs'); 124 | $plugin = ''; 125 | if (in_array($item['obfs'], $ss_obfs_list)) { 126 | if (strpos($item['obfs'], 'http') !== false) { 127 | $plugin .= ', obfs=http'; 128 | } else { 129 | $plugin .= ', obfs=tls'; 130 | } 131 | if ($item['obfs_param'] != '') { 132 | $plugin .= ', obfs-host=' . $item['obfs_param']; 133 | } else { 134 | $plugin .= ', obfs-host=wns.windows.com'; 135 | } 136 | } 137 | return $plugin; 138 | } 139 | 140 | public static function getQuantumultURI(array $item, bool $base64_encode = false) 141 | { 142 | $return = null; 143 | switch ($item['type']) { 144 | case 'ss': 145 | if ($item['obfs'] == 'v2ray') { 146 | break; 147 | } 148 | $return = ($item['remark'] . ' = shadowsocks, ' . $item['address'] . ', ' . $item['port'] . ', ' . $item['method'] . ', "' . $item['passwd'] . '", upstream-proxy=false, upstream-proxy-auth=false' . self::getSurgeObfs($item) . ', group=' . Config::getInstance()->getConf('appName') . '_ss'); 149 | break; 150 | case 'ssr': 151 | $return = ($item['remark'] . ' = shadowsocksr, ' . $item['address'] . ', ' . $item['port'] . ', ' . $item['method'] . ', "' . $item['passwd'] . '", protocol=' . $item['protocol'] . ', protocol_param=' . $item['protocol_param'] . ', obfs=' . $item['obfs'] . ', obfs_param="' . $item['obfs_param'] . '", group=' . Config::getInstance()->getConf('appName')); 152 | break; 153 | case 'vmess': 154 | if (!in_array($item['net'], ['ws', 'tcp', 'http'])) { 155 | break; 156 | } 157 | $tls = ', over-tls=false, certificate=1'; 158 | if ($item['tls'] == 'tls') { 159 | $tls = ', over-tls=true, tls-host=' . $item['host']; 160 | if ($item['verify_cert']) { 161 | $tls .= ', certificate=1'; 162 | } else { 163 | $tls .= ', certificate=0'; 164 | } 165 | } 166 | $obfs = ''; 167 | if (in_array($item['net'], ['ws', 'http'])) { 168 | $obfs = ', obfs=' . $item['net'] . ', obfs-path="' . $item['path'] . '", obfs-header="Host: ' . $item['host'] . '[Rr][Nn]User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_0 like Mac OS X) AppleWebKit/888.8.88 (KHTML, like Gecko) Mobile/6666666"'; 169 | } 170 | $return = ($item['remark'] . ' = vmess, ' . $item['add'] . ', ' . $item['port'] . ', chacha20-ietf-poly1305, "' . $item['id'] . '", group=' . Config::getInstance()->getConf('appName') . '_VMess' . $tls . $obfs); 171 | if ($base64_encode === true) { 172 | $return = 'vmess://' . base64_encode($return); 173 | } 174 | break; 175 | } 176 | return $return; 177 | } 178 | 179 | public static function getQuantumultXURI(array $item) 180 | { 181 | $return = null; 182 | switch ($item['type']) { 183 | case 'ss': 184 | // ;shadowsocks=example.com:80, method=chacha20, password=pwd, obfs=http, obfs-host=bing.com, obfs-uri=/resource/file, fast-open=false, udp-relay=false, server_check_url=http://www.apple.com/generate_204, tag=ss-01 185 | // ;shadowsocks=example.com:80, method=chacha20, password=pwd, obfs=http, obfs-host=bing.com, obfs-uri=/resource/file, fast-open=false, udp-relay=false, tag=ss-02 186 | // ;shadowsocks=example.com:443, method=chacha20, password=pwd, obfs=tls, obfs-host=bing.com, fast-open=false, udp-relay=false, tag=ss-03 187 | // ;shadowsocks=example.com:80, method=aes-128-gcm, password=pwd, obfs=ws, fast-open=false, udp-relay=false, tag=ss-ws-01 188 | // ;shadowsocks=example.com:80, method=aes-128-gcm, password=pwd, obfs=ws, obfs-uri=/ws, fast-open=false, udp-relay=false, tag=ss-ws-02 189 | // ;shadowsocks=example.com:443, method=aes-128-gcm, password=pwd, obfs=wss, obfs-uri=/ws, fast-open=false, udp-relay=false, tag=ss-ws-tls 190 | $return = ('shadowsocks=' . $item['address'] . ':' . $item['port'] . ', method=' . $item['method'] . ', password=' . $item['passwd']); 191 | switch ($item['obfs']) { 192 | case 'simple_obfs_http': 193 | $return .= ', obfs=http'; 194 | $return .= ($item['obfs_param'] != '' ? ', obfs-host=' . $item['obfs_param'] : ', obfs-host=wns.windows.com'); 195 | $return .= ', obfs-uri=/'; 196 | break; 197 | case 'simple_obfs_tls': 198 | $return .= ', obfs=tls'; 199 | $return .= ($item['obfs_param'] != '' ? ', obfs-host=' . $item['obfs_param'] : ', obfs-host=wns.windows.com'); 200 | $return .= ', obfs-uri=/'; 201 | break; 202 | case 'v2ray'; 203 | $return .= ($item['tls'] == 'tls' ? ', obfs=wss' : ', obfs=ws'); 204 | $return .= ', obfs-uri=' . $item['path'] . ', obfs-host=' . $item['host']; 205 | break; 206 | } 207 | $return .= (', tag=' . $item['remark']); 208 | break; 209 | case 'ssr': 210 | // ;shadowsocks=example.com:443, method=chacha20, password=pwd, ssr-protocol=auth_chain_b, ssr-protocol-param=def, obfs=tls1.2_ticket_fastauth, obfs-host=bing.com, tag=ssr 211 | $return = ('shadowsocks=' . $item['address'] . ':' . $item['port'] . ', method=' . $item['method'] . ', password=' . $item['passwd']); 212 | $return .= (', ssr-protocol=' . $item['protocol']); 213 | $return .= (', ssr-protocol-param=' . $item['protocol_param']); 214 | $return .= (', obfs=' . $item['obfs']); 215 | $return .= (', obfs-host="' . $item['obfs_param']); 216 | $return .= (', tag=' . $item['remark']); 217 | break; 218 | case 'vmess': 219 | // ;vmess=example.com:80, method=none, password=23ad6b10-8d1a-40f7-8ad0-e3e35cd32291, fast-open=false, udp-relay=false, tag=vmess-01 220 | // ;vmess=example.com:80, method=aes-128-gcm, password=23ad6b10-8d1a-40f7-8ad0-e3e35cd32291, fast-open=false, udp-relay=false, tag=vmess-02 221 | // ;vmess=example.com:443, method=none, password=23ad6b10-8d1a-40f7-8ad0-e3e35cd32291, obfs=over-tls, fast-open=false, udp-relay=false, tag=vmess-tls 222 | // ;vmess=example.com:80, method=chacha20-poly1305, password=23ad6b10-8d1a-40f7-8ad0-e3e35cd32291, obfs=ws, obfs-uri=/ws, fast-open=false, udp-relay=false, tag=vmess-ws 223 | // ;vmess=example.com:443, method=chacha20-poly1305, password=23ad6b10-8d1a-40f7-8ad0-e3e35cd32291, obfs=wss, obfs-uri=/ws, fast-open=false, udp-relay=false, tag=vmess-ws-tls 224 | if (!in_array($item['net'], ['ws', 'tcp'])) { 225 | break; 226 | } 227 | $return = ('vmess=' . $item['add'] . ':' . $item['port'] . ', method=chacha20-poly1305' . ', password=' . $item['id']); 228 | switch ($item['net']) { 229 | case 'ws': 230 | $return .= ($item['tls'] == 'tls' ? ', obfs=wss' : ', obfs=ws'); 231 | $return .= ', obfs-uri=' . $item['path'] . ', obfs-host=' . $item['host']; 232 | break; 233 | case 'tcp': 234 | $return .= ($item['tls'] == 'tls' ? ', obfs=over-tls' : ''); 235 | break; 236 | } 237 | $return .= (', tag=' . $item['remark']); 238 | break; 239 | case 'trojan': 240 | // ;trojan=example.com:443, password=pwd, over-tls=true, tls-verification=true, fast-open=false, udp-relay=false, tag=trojan-tls-01 241 | $return = ('trojan=' . $item['address'] . ':' . $item['port'] . ', password=' . $item['passwd']); 242 | $return .= ', over-tls=true, tls-verification=true'; 243 | $return .= (', tag=' . $item['remark']); 244 | break; 245 | } 246 | return $return; 247 | } 248 | 249 | public static function getSurfboardURI(array $item) 250 | { 251 | $return = null; 252 | switch ($item['type']) { 253 | case 'ss': 254 | if ($item['obfs'] == 'v2ray') { 255 | break; 256 | } 257 | $return = ($item['remark'] . ' = custom, ' . $item['address'] . ', ' . $item['port'] . ', ' . $item['method'] . ', ' . $item['passwd'] . ', https://raw.githubusercontent.com/lhie1/Rules/master/SSEncrypt.module' . self::getSurgeObfs($item)); 258 | break; 259 | case 'vmess': 260 | if (!in_array($item['net'], ['ws', 'tcp'])) { 261 | break; 262 | } 263 | $tls = ($item['tls'] == 'tls' 264 | ? ', tls=true' 265 | : ''); 266 | $ws = ($item['net'] == 'ws' 267 | ? ', ws=true, ws-path=' . $item['path'] . ', ws-headers=host:' . $item['host'] 268 | : ''); 269 | $return = $item['remark'] . ' = vmess, ' . $item['add'] . ', ' . $item['port'] . ', username = ' . $item['id'] . $ws . $tls; 270 | break; 271 | } 272 | return $return; 273 | } 274 | 275 | public static function getClashURI(array $item, bool $ssr_support = false) 276 | { 277 | $return = null; 278 | if ($item['type'] == 'ssr' && $ssr_support === false) { 279 | return $return; 280 | } 281 | switch ($item['type']) { 282 | case 'ss': 283 | $method = ['rc4-md5-6', 'camellia-128-cfb', 'camellia-192-cfb', 'camellia-256-cfb', 'bf-cfb', 'cast5-cfb', 'des-cfb', 'des-ede3-cfb', 'idea-cfb', 'rc2-cfb', 'seed-cfb', 'salsa20', 'chacha20', 'xsalsa20', 'none']; 284 | if (in_array($item['method'], $method)) { 285 | // 不支持的 286 | break; 287 | } 288 | $return = [ 289 | 'name' => $item['remark'], 290 | 'type' => 'ss', 291 | 'server' => $item['address'], 292 | 'port' => $item['port'], 293 | 'cipher' => $item['method'], 294 | 'password' => $item['passwd'], 295 | 'udp' => true 296 | ]; 297 | if ($item['obfs'] != 'plain') { 298 | switch ($item['obfs']) { 299 | case 'simple_obfs_http': 300 | $return['plugin'] = 'obfs'; 301 | $return['plugin-opts']['mode'] = 'http'; 302 | break; 303 | case 'simple_obfs_tls': 304 | $return['plugin'] = 'obfs'; 305 | $return['plugin-opts']['mode'] = 'tls'; 306 | break; 307 | case 'v2ray': 308 | $return['plugin'] = 'v2ray-plugin'; 309 | $return['plugin-opts']['mode'] = 'websocket'; 310 | if ($item['tls'] == 'tls') { 311 | $return['plugin-opts']['tls'] = true; 312 | if ($item['verify_cert'] == false) { 313 | $return['plugin-opts']['skip-cert-verify'] = true; 314 | } 315 | } 316 | $return['plugin-opts']['host'] = $item['host']; 317 | $return['plugin-opts']['path'] = $item['path']; 318 | break; 319 | } 320 | if ($item['obfs'] != 'v2ray') { 321 | if ($item['obfs_param'] != '') { 322 | $return['plugin-opts']['host'] = $item['obfs_param']; 323 | } else { 324 | $return['plugin-opts']['host'] = 'windowsupdate.windows.com'; 325 | } 326 | } 327 | } 328 | break; 329 | case 'ssr': 330 | // if ( 331 | // in_array($item['method'], ['rc4-md5-6', 'des-ede3-cfb', 'xsalsa20', 'none']) 332 | // || 333 | // in_array($item['protocol'], array_merge(Config::getSupportParam('allow_none_protocol'), ['verify_deflate'])) 334 | // || 335 | // in_array($item['obfs'], ['tls1.2_ticket_fastauth']) 336 | // ) { 337 | // // 不支持的 338 | // break; 339 | // } 340 | $return = [ 341 | 'name' => $item['remark'], 342 | 'type' => 'ssr', 343 | 'server' => $item['address'], 344 | 'port' => $item['port'], 345 | 'cipher' => $item['method'], 346 | 'password' => $item['passwd'], 347 | 'protocol' => $item['protocol'], 348 | 'protocolparam' => $item['protocol_param'], 349 | 'obfs' => $item['obfs'], 350 | 'obfsparam' => $item['obfs_param'] 351 | ]; 352 | break; 353 | case 'vmess': 354 | if (!in_array($item['net'], array('ws', 'tcp'))) { 355 | break; 356 | } 357 | $return = [ 358 | 'name' => $item['remark'], 359 | 'type' => 'vmess', 360 | 'server' => $item['add'], 361 | 'port' => $item['port'], 362 | 'uuid' => $item['id'], 363 | 'alterId' => $item['aid'], 364 | 'cipher' => 'auto', 365 | 'udp' => true 366 | ]; 367 | if ($item['net'] == 'ws') { 368 | $return['network'] = 'ws'; 369 | $return['ws-path'] = $item['path']; 370 | $return['ws-headers']['Host'] = ($item['host'] != '' ? $item['host'] : $item['add']); 371 | } 372 | if ($item['tls'] == 'tls') { 373 | $return['tls'] = true; 374 | if ($item['verify_cert'] == false) { 375 | $return['skip-cert-verify'] = true; 376 | } 377 | } 378 | break; 379 | case 'trojan': 380 | $return = [ 381 | 'name' => $item['remark'], 382 | 'type' => 'trojan', 383 | 'server' => $item['address'], 384 | 'port' => $item['port'], 385 | 'password' => $item['passwd'] 386 | ]; 387 | break; 388 | } 389 | return $return; 390 | } 391 | 392 | public static function getShadowrocketURI(array $item) 393 | { 394 | $return = null; 395 | switch ($item['type']) { 396 | case 'ss': 397 | if (in_array($item['obfs'], Tools::getSupportParam('ss_obfs'))) { 398 | $return = (self::getItemUrl($item, 1)); 399 | } else { 400 | if ($item['obfs'] == 'v2ray') { 401 | $v2rayplugin = [ 402 | 'address' => $item['address'], 403 | 'port' => (string) $item['port'], 404 | 'path' => $item['path'], 405 | 'host' => $item['host'], 406 | 'mode' => 'websocket', 407 | ]; 408 | $v2rayplugin['tls'] = $item['tls'] == 'tls' ? true : false; 409 | $return = ('ss://' . Tools::base64_url_encode($item['method'] . ':' . $item['passwd'] . '@' . $item['address'] . ':' . $item['port']) . '?v2ray-plugin=' . base64_encode(json_encode($v2rayplugin)) . '#' . rawurlencode($item['remark'])); 410 | } 411 | if ($item['obfs'] == 'plain') { 412 | $return = (self::getItemUrl($item, 2)); 413 | } 414 | } 415 | break; 416 | case 'ssr': 417 | $return = (self::getItemUrl($item, 0)); 418 | break; 419 | case 'vmess': 420 | if (!in_array($item['net'], ['tcp', 'ws', 'http', 'h2'])) { 421 | break; 422 | } 423 | $obfs = ''; 424 | switch ($item['net']) { 425 | case 'ws': 426 | $obfs .= ($item['host'] != '' 427 | ? ('&obfsParam=' . $item['host'] . '&path=' . $item['path'] . '&obfs=websocket') 428 | : ('&obfsParam=' . $item['add'] . '&path=' . $item['path'] . '&obfs=websocket')); 429 | break; 430 | case 'kcp': 431 | $obfs .= 'obfsParam={"header":' . '"' . ($item['headerType'] == '' || $item['headerType'] == 'noop' ? 'none' : $item['headerType']) . '"' . '}&obfs=mkcp'; 432 | break; 433 | case 'mkcp': 434 | $obfs .= 'obfsParam={"header":' . '"' . ($item['headerType'] == '' || $item['headerType'] == 'noop' ? 'none' : $item['headerType']) . '"' . '}&obfs=mkcp'; 435 | break; 436 | case 'h2': 437 | $obfs .= ($item['host'] != '' 438 | ? ('&obfsParam=' . $item['host'] . '&path=' . $item['path'] . '&obfs=h2') 439 | : ('&obfsParam=' . $item['add'] . '&path=' . $item['path'] . '&obfs=h2')); 440 | break; 441 | default: 442 | $obfs .= '&obfs=none'; 443 | break; 444 | } 445 | $tls = ''; 446 | if ($item['tls'] == 'tls') { 447 | $tls = '&tls=1'; 448 | if ($item['verify_cert'] == false) { 449 | $tls .= '&allowInsecure=1'; 450 | } 451 | if (isset($item['localserver'])) { 452 | $tls .= '&peer=' . $item['localserver']; 453 | } 454 | } 455 | $return = ('vmess://' . Tools::base64_url_encode('chacha20-poly1305:' . $item['id'] . '@' . $item['add'] . ':' . $item['port']) . '?remarks=' . rawurlencode($item['remark']) . $obfs . $tls); 456 | break; 457 | case 'trojan': 458 | $return = ('trojan://' . $item['passwd'] . '@' . $item['address'] . ':' . $item['port']); 459 | $return .= ('#' . rawurlencode($item['remark'])); 460 | break; 461 | } 462 | return $return; 463 | } 464 | 465 | public static function getKitsunebiURI(array $item) 466 | { 467 | $return = null; 468 | switch ($item['type']) { 469 | case 'ss': 470 | if (in_array($item['obfs'], ['v2ray', 'simple_obfs_http', 'simple_obfs_tls'])) { 471 | break; 472 | } 473 | $return = (self::getItemUrl($item, 2)); 474 | break; 475 | case 'vmess': 476 | $network = ($item['net'] == 'tls' 477 | ? '&network=tcp' 478 | : ('&network=' . $item['net'])); 479 | $protocol = ''; 480 | switch ($item['net']) { 481 | case 'kcp': 482 | $protocol .= ('&kcpheader=' . $item['headerType']); 483 | break; 484 | case 'ws': 485 | $protocol .= ('&wspath=' . $item['path'] . '&wsHost=' . $item['host']); 486 | break; 487 | case 'h2': 488 | $protocol .= ('&h2Path=' . $item['path'] . '&h2Host=' . $item['host']); 489 | break; 490 | } 491 | $tls = ''; 492 | if ($item['tls'] == 'tls') { 493 | $tls = '&tls=1'; 494 | if ($item['verify_cert'] == false) { 495 | $tls .= '&allowInsecure=1'; 496 | } 497 | } 498 | $return .= ('vmess://' . base64_encode('auto:' . $item['id'] . '@' . $item['add'] . ':' . $item['port']) . '?remark=' . rawurlencode($item['remark']) . $network . $protocol . '&aid=' . $item['aid'] . $tls); 499 | break; 500 | } 501 | return $return; 502 | } 503 | 504 | public static function getSSDURI(array $item) 505 | { 506 | $return = null; 507 | switch ($item['type']) { 508 | case 'ss': 509 | $return['remarks'] = $item['remark']; 510 | $return['server'] = $item['address']; 511 | $return['port'] = $item['port']; 512 | $return['encryption'] = $item['method']; 513 | $return['password'] = $item['passwd']; 514 | $plugin_options = ''; 515 | if ($item['obfs'] != 'plain') { 516 | switch ($item['obfs']) { 517 | case 'simple_obfs_http': 518 | $return['plugin'] = 'simple-obfs'; 519 | $plugin_options .= 'obfs=http;obfs-host=' . $item['obfs_param']; 520 | break; 521 | case 'simple_obfs_tls': 522 | $return['plugin'] = 'simple-obfs'; 523 | $plugin_options .= 'obfs=tls;obfs-host=' . $item['obfs_param']; 524 | break; 525 | case 'v2ray': 526 | $return['plugin'] = 'v2ray'; 527 | if ($item['net'] == 'ws') { 528 | $plugin_options .= 'mode=ws'; 529 | } 530 | if ($item['tls'] == 'tls') { 531 | $plugin_options .= ';security=tls'; 532 | } else { 533 | $plugin_options .= ';security=none'; 534 | } 535 | $plugin_options .= ';path=' . $item['path']; 536 | if ($item['host'] != '') { 537 | $plugin_options .= ';host=' . $item['host']; 538 | } else { 539 | $plugin_options .= ';host=' . $item['address']; 540 | } 541 | break; 542 | } 543 | } 544 | $return['plugin_options'] = $plugin_options; 545 | $return['ratio'] = $item['ratio']; 546 | break; 547 | } 548 | return $return; 549 | } 550 | 551 | public static function getSSJSON(array $item) 552 | { 553 | $return = null; 554 | switch ($item['type']) { 555 | case 'ss': 556 | $return['remarks'] = $item['remark']; 557 | $return['server'] = $item['address']; 558 | $return['server_port'] = $item['port']; 559 | $return['method'] = $item['method']; 560 | $return['password'] = $item['passwd']; 561 | if ($item['obfs'] != 'plain') { 562 | $plugin_options = ''; 563 | switch ($item['obfs']) { 564 | case 'simple_obfs_http': 565 | $return['plugin'] = 'simple-obfs'; 566 | $plugin_options .= 'obfs=http;obfs-host=' . $item['obfs_param']; 567 | break; 568 | case 'simple_obfs_tls': 569 | $return['plugin'] = 'simple-obfs'; 570 | $plugin_options .= 'obfs=tls;obfs-host=' . $item['obfs_param']; 571 | break; 572 | case 'v2ray': 573 | $return['plugin'] = 'v2ray'; 574 | if ($item['net'] == 'ws') { 575 | $plugin_options .= 'mode=ws'; 576 | } 577 | if ($item['tls'] == 'tls') { 578 | $plugin_options .= ';security=tls'; 579 | } else { 580 | $plugin_options .= ';security=none'; 581 | } 582 | $plugin_options .= ';path=' . $item['path']; 583 | if ($item['host'] != '') { 584 | $plugin_options .= ';host=' . $item['host']; 585 | } else { 586 | $plugin_options .= ';host=' . $item['address']; 587 | } 588 | break; 589 | } 590 | $return['plugin_opts'] = $plugin_options; 591 | } 592 | break; 593 | } 594 | return $return; 595 | } 596 | 597 | public static function getTrojanURI(array $item) 598 | { 599 | $return = null; 600 | switch ($item['type']) { 601 | case 'trojan': 602 | $return = ('trojan://' . $item['passwd'] . '@' . $item['address'] . ':' . $item['port']); 603 | $return .= ('#' . rawurlencode($item['remark'])); 604 | break; 605 | } 606 | return $return; 607 | } 608 | } 609 | -------------------------------------------------------------------------------- /App/Utils/Conf.php: -------------------------------------------------------------------------------- 1 | getMessage()); 69 | } 70 | } 71 | 72 | /** 73 | * 自定义配置文件生成 Surge 托管配置 74 | * 75 | * @param User $User 用户 76 | * @param string $AllProxys Surge 格式的全部节点 77 | * @param array $Nodes 节点数组 78 | * @param string $SourceContent 配置内容 79 | * 80 | * @return string 81 | */ 82 | public static function getSurgeConfs($User, $AllProxys, $Nodes, $Configs, $URL) 83 | { 84 | $General = (isset($Configs['General']) ? self::getSurgeConfGeneral($Configs['General']) : ''); 85 | 86 | $Proxys = (isset($Configs['Proxy']) ? self::getSurgeConfProxy($Configs['Proxy']) : ''); 87 | 88 | if (isset($Configs['Proxy Group'])) { 89 | //兼容 90 | $Configs['ProxyGroup'] = $Configs['Proxy Group']; 91 | } 92 | $ProxyGroups = self::getSurgeConfProxyGroup( 93 | $Nodes, 94 | $Configs['ProxyGroup'] 95 | ); 96 | $ProxyGroup = self::fixSurgeProxyGroup($ProxyGroups, $Configs['Checks']); 97 | $ProxyGroup = self::getSurgeProxyGroup2String($ProxyGroups); 98 | 99 | $Rule = self::getRule($Configs['Rule']); 100 | 101 | $Conf = [ 102 | '#!MANAGED-CONFIG ' . $URL, 103 | '', 104 | '#---------------------------------------------------#', 105 | '## 上次更新于:' . date("Y-m-d h:i:s"), 106 | '#---------------------------------------------------#', 107 | '', 108 | '[General]', 109 | $General, 110 | '', 111 | '[Proxy]', 112 | $Proxys, 113 | $AllProxys, 114 | '', 115 | '[Proxy Group]', 116 | $ProxyGroup, 117 | '', 118 | '[Rule]', 119 | $Rule 120 | ]; 121 | 122 | return implode(PHP_EOL, $Conf); 123 | } 124 | 125 | /** 126 | * Surge 配置中的 General 127 | * 128 | * @param array $General Surge General 定义 129 | * 130 | * @return string 131 | */ 132 | public static function getSurgeConfGeneral($General) 133 | { 134 | $return = ''; 135 | if (count($General) != 0) { 136 | foreach ($General as $key => $value) { 137 | $return .= $key . ' = ' . $value . PHP_EOL; 138 | } 139 | } 140 | return $return; 141 | } 142 | 143 | /** 144 | * Surge 配置中的 Proxy 145 | * 146 | * @param array $Proxys 自定义配置中的额外 Proxy 147 | * 148 | * @return string 149 | */ 150 | public static function getSurgeConfProxy($Proxys) 151 | { 152 | $return = ''; 153 | if (count($Proxys) != 0) { 154 | foreach ($Proxys as $value) { 155 | if (!preg_match('/(\[General|Replica|Proxy|Proxy\sGroup|Rule|Host|URL\sRewrite|Header\sRewrite|MITM|Script\])/', $value)) { 156 | $return .= $value . PHP_EOL; 157 | } 158 | } 159 | } 160 | return $return; 161 | } 162 | 163 | /** 164 | * Surge 配置中的 ProxyGroup 165 | * 166 | * @param array $Nodes 全部节点数组 167 | * @param array $ProxyGroups Surge 策略组定义 168 | * 169 | * @return array 170 | */ 171 | public static function getSurgeConfProxyGroup($Nodes, $ProxyGroups) 172 | { 173 | $return = []; 174 | foreach ($ProxyGroups as $ProxyGroup) { 175 | if (in_array($ProxyGroup['type'], ['select', 'url-test', 'fallback', 'load-balance'])) { 176 | $proxies = []; 177 | if ( 178 | isset($ProxyGroup['content']['left-proxies']) 179 | && count($ProxyGroup['content']['left-proxies']) != 0 180 | ) { 181 | $proxies = $ProxyGroup['content']['left-proxies']; 182 | } 183 | foreach ($Nodes as $item) { 184 | $item = self::getMatchProxy($item, $ProxyGroup); 185 | if ($item !== null && !in_array($item['remark'], $proxies)) { 186 | $proxies[] = $item['remark']; 187 | } 188 | } 189 | if (isset($ProxyGroup['content']['right-proxies'])) { 190 | $proxies = array_merge($proxies, $ProxyGroup['content']['right-proxies']); 191 | } 192 | $ProxyGroup['proxies'] = $proxies; 193 | } 194 | $return[] = $ProxyGroup; 195 | } 196 | 197 | return $return; 198 | } 199 | 200 | /** 201 | * Surge ProxyGroup 去除无用策略组 202 | * 203 | * @param array $ProxyGroups 策略组 204 | * @param array $checks 要检查的策略组名 205 | * 206 | * @return array 207 | */ 208 | public static function fixSurgeProxyGroup($ProxyGroups, $checks) 209 | { 210 | if (count($checks) == 0) { 211 | return $ProxyGroups; 212 | } 213 | $clean_names = []; 214 | $newProxyGroups = []; 215 | foreach ($ProxyGroups as $ProxyGroup) { 216 | if (in_array($ProxyGroup['name'], $checks) && count($ProxyGroup['proxies']) == 0) { 217 | $clean_names[] = $ProxyGroup['name']; 218 | continue; 219 | } 220 | $newProxyGroups[] = $ProxyGroup; 221 | } 222 | if (count($clean_names) >= 1) { 223 | $ProxyGroups = $newProxyGroups; 224 | $newProxyGroups = []; 225 | foreach ($ProxyGroups as $ProxyGroup) { 226 | if (!in_array($ProxyGroup['name'], $checks) && $ProxyGroup['type'] != 'ssid') { 227 | $newProxies = []; 228 | foreach ($ProxyGroup['proxies'] as $proxie) { 229 | if (!in_array($proxie, $clean_names)) { 230 | $newProxies[] = $proxie; 231 | } 232 | } 233 | $ProxyGroup['proxies'] = $newProxies; 234 | } 235 | $newProxyGroups[] = $ProxyGroup; 236 | } 237 | } 238 | 239 | return $newProxyGroups; 240 | } 241 | 242 | /** 243 | * Surge ProxyGroup 转字符串 244 | * 245 | * @param array $ProxyGroups Surge 策略组定义 246 | * 247 | * @return string 248 | */ 249 | public static function getSurgeProxyGroup2String($ProxyGroups) 250 | { 251 | $return = ''; 252 | foreach ($ProxyGroups as $ProxyGroup) { 253 | $str = ''; 254 | if (in_array($ProxyGroup['type'], ['select', 'url-test', 'fallback', 'load-balance'])) { 255 | $proxies = implode(', ', $ProxyGroup['proxies']); 256 | if (in_array($ProxyGroup['type'], ['url-test', 'fallback', 'load-balance'])) { 257 | $str .= ($ProxyGroup['name'] 258 | . ' = ' 259 | . $ProxyGroup['type'] 260 | . ', ' 261 | . $proxies 262 | . ', url = ' . $ProxyGroup['url'] 263 | . ', interval = ' . $ProxyGroup['interval']); 264 | } else { 265 | $str .= ($ProxyGroup['name'] 266 | . ' = ' 267 | . $ProxyGroup['type'] 268 | . ', ' 269 | . $proxies); 270 | } 271 | } elseif ($ProxyGroup['type'] == 'ssid') { 272 | $wifi = ''; 273 | foreach ($ProxyGroup['content'] as $key => $value) { 274 | $wifi .= ', "' . $key . '" = ' . $value; 275 | } 276 | $cellular = (isset($ProxyGroup['cellular']) 277 | ? ', cellular = ' . $ProxyGroup['cellular'] 278 | : ''); 279 | $str .= ($ProxyGroup['name'] 280 | . ' = ' 281 | . $ProxyGroup['type'] 282 | . ', default = ' 283 | . $ProxyGroup['default'] 284 | . $cellular 285 | . $wifi); 286 | } else { 287 | $str .= ''; 288 | } 289 | $return .= $str . PHP_EOL; 290 | } 291 | return $return; 292 | } 293 | 294 | /** 295 | * 自定义配置文件生成 Clash 配置 296 | * 297 | * @param object $User 用户 298 | * @param array $AllProxys 全部节点数组 299 | * @param string $SourceContent 远程配置内容 300 | * 301 | * @return string 302 | */ 303 | public static function getClashConfs($User, $AllProxys, $Configs) 304 | { 305 | if (isset($Configs['Proxy']) && count($Configs['Proxy']) != 0) { 306 | $tmpProxys = array_merge($AllProxys, $Configs['Proxy']); 307 | } else { 308 | $tmpProxys = $AllProxys; 309 | } 310 | $Proxys = []; 311 | foreach ($tmpProxys as $Proxy) { 312 | unset($Proxy['class']); 313 | $Proxys[] = $Proxy; 314 | } 315 | 316 | $tmp = $Configs['General']; 317 | $tmp['proxies'] = $Proxys; 318 | if (isset($Configs['Proxy Group'])) { 319 | $Configs['ProxyGroup'] = $Configs['Proxy Group']; 320 | } 321 | $tmp['proxy-groups'] = self::getClashConfProxyGroup( 322 | $AllProxys, 323 | $Configs['ProxyGroup'] 324 | ); 325 | 326 | $Conf = [ 327 | '#---------------------------------------------------#', 328 | '## 上次更新于:' . date("Y-m-d h:i:s"), 329 | '#---------------------------------------------------#', 330 | '', 331 | Yaml::dump($tmp, 4, 2), 332 | '', 333 | 'rules:', 334 | self::getRule($Configs['Rule']) 335 | ]; 336 | 337 | return implode(PHP_EOL, $Conf); 338 | } 339 | 340 | /** 341 | * Clash 配置中的 ProxyGroup 342 | * 343 | * @param array $Nodes 全部节点数组 344 | * @param array $ProxyGroups Clash 策略组定义 345 | * 346 | * @return array 347 | */ 348 | public static function getClashConfProxyGroup($Nodes, $ProxyGroups) 349 | { 350 | $return = []; 351 | foreach ($ProxyGroups as $ProxyGroup) { 352 | $tmp = []; 353 | if (in_array($ProxyGroup['type'], ['select', 'url-test', 'fallback', 'load-balance'])) { 354 | $proxies = []; 355 | if ( 356 | isset($ProxyGroup['content']['left-proxies']) 357 | && count($ProxyGroup['content']['left-proxies']) != 0 358 | ) { 359 | $proxies = $ProxyGroup['content']['left-proxies']; 360 | } 361 | foreach ($Nodes as $item) { 362 | $item['remark'] = $item['name']; 363 | $item = self::getMatchProxy($item, $ProxyGroup); 364 | if ($item !== null && !in_array($item['name'], $proxies)) { 365 | $proxies[] = $item['name']; 366 | } 367 | } 368 | if (isset($ProxyGroup['content']['right-proxies'])) { 369 | $proxies = array_merge($proxies, $ProxyGroup['content']['right-proxies']); 370 | } 371 | $tmp = [ 372 | 'name' => $ProxyGroup['name'], 373 | 'type' => $ProxyGroup['type'], 374 | 'proxies' => $proxies 375 | ]; 376 | if ($ProxyGroup['type'] != 'select') { 377 | $tmp['url'] = $ProxyGroup['url']; 378 | $tmp['interval'] = $ProxyGroup['interval']; 379 | } 380 | $return[] = $tmp; 381 | } 382 | } 383 | return $return; 384 | } 385 | 386 | /** 387 | * Clash ProxyGroup 去除无用策略组 388 | * 389 | * @param array $ProxyGroups 策略组 390 | * @param array $checks 要检查的策略组名 391 | * 392 | * @return array 393 | */ 394 | public static function fixClashProxyGroup($ProxyGroups, $checks) 395 | { 396 | if (count($checks) == 0) { 397 | return $ProxyGroups; 398 | } 399 | $clean_names = []; 400 | $newProxyGroups = []; 401 | foreach ($ProxyGroups as $ProxyGroup) { 402 | if (in_array($ProxyGroup['name'], $checks) && count($ProxyGroup['proxies']) == 0) { 403 | $clean_names[] = $ProxyGroup['name']; 404 | continue; 405 | } 406 | $newProxyGroups[] = $ProxyGroup; 407 | } 408 | if (count($clean_names) >= 1) { 409 | $ProxyGroups = $newProxyGroups; 410 | $newProxyGroups = []; 411 | foreach ($ProxyGroups as $ProxyGroup) { 412 | if (!in_array($ProxyGroup['name'], $checks)) { 413 | $newProxies = []; 414 | foreach ($ProxyGroup['proxies'] as $proxie) { 415 | if (!in_array($proxie, $clean_names)) { 416 | $newProxies[] = $proxie; 417 | } 418 | } 419 | $ProxyGroup['proxies'] = $newProxies; 420 | } 421 | $newProxyGroups[] = $ProxyGroup; 422 | } 423 | } 424 | 425 | return $newProxyGroups; 426 | } 427 | 428 | /** 429 | * 规则加载 430 | * 431 | * @param array $Rules 规则加载地址 432 | * 433 | * @return string 434 | */ 435 | public static function getRule($Rules) 436 | { 437 | $path = EASYSWOOLE_ROOT . '/Resources/Conf/' . $Rules['source']; 438 | if (!is_file($path)) { 439 | return 'not found file.'; 440 | } 441 | 442 | return @file_get_contents($path); 443 | } 444 | } 445 | -------------------------------------------------------------------------------- /App/Utils/Subcribe.php: -------------------------------------------------------------------------------- 1 | getConf('subUrl') . $user->getSubToken(); 24 | $return_info = [ 25 | 'link' => '', 26 | // sub 27 | 'ss' => '?sub=2', 28 | 'ssr' => '?sub=1', 29 | 'v2ray' => '?sub=3', 30 | 'trojan' => '?sub=4', 31 | // apps 32 | 'ssa' => '?list=ssa', 33 | 'ssd' => '?ssd=1', 34 | 'clash' => '?clash=1', 35 | 'clash_provider' => '?list=clash', 36 | 'clashr' => '?clash=2', 37 | 'clashr_provider' => '?list=clashr', 38 | 'surge' => '?surge=' . $int, 39 | 'surge_node' => '?list=surge', 40 | 'surge2' => '?surge=2', 41 | 'surge3' => '?surge=3', 42 | 'surge4' => '?surge=4', 43 | 'surfboard' => '?surfboard=1', 44 | 'quantumult' => '?quantumult=' . $int, 45 | 'quantumult_v2' => '?list=quantumult', 46 | 'quantumult_sub' => '?quantumult=2', 47 | 'quantumult_conf' => '?quantumult=3', 48 | 'quantumultx' => '?list=quantumultx', 49 | 'shadowrocket' => '?list=shadowrocket', 50 | 'kitsunebi' => '?list=kitsunebi' 51 | ]; 52 | 53 | return array_map( 54 | function ($item) use ($userapiUrl) { 55 | return ($userapiUrl . $item); 56 | }, 57 | $return_info 58 | ); 59 | } 60 | 61 | /** 62 | * Undocumented function 63 | * 64 | * @param array $item 65 | * @param string $list 66 | */ 67 | public static function getListItem(array $item, string $list) 68 | { 69 | $return = null; 70 | switch ($list) { 71 | case 'ss': 72 | $return = AppURI::getItemUrl($item, 1); 73 | break; 74 | case 'ssr': 75 | $return = AppURI::getItemUrl($item, 0); 76 | break; 77 | case 'ssa': 78 | $return = AppURI::getSSJSON($item); 79 | break; 80 | case 'surge': 81 | $return = AppURI::getSurgeURI($item, 3); 82 | break; 83 | case 'clash': 84 | $return = AppURI::getClashURI($item); 85 | break; 86 | case 'clashr': 87 | $return = AppURI::getClashURI($item, true); 88 | break; 89 | case 'v2rayn': 90 | $return = AppURI::getV2RayNURI($item); 91 | break; 92 | case 'trojan': 93 | $return = AppURI::getTrojanURI($item); 94 | break; 95 | case 'kitsunebi': 96 | $return = AppURI::getKitsunebiURI($item); 97 | break; 98 | case 'quantumult': 99 | $return = AppURI::getQuantumultURI($item, true); 100 | break; 101 | case 'quantumultx': 102 | $return = AppURI::getQuantumultXURI($item); 103 | break; 104 | case 'shadowrocket': 105 | $return = AppURI::getShadowrocketURI($item); 106 | break; 107 | } 108 | return $return; 109 | } 110 | 111 | /** 112 | * Undocumented function 113 | * 114 | * @param User $user 115 | * @param string $list 116 | * @param array $opts 117 | * @param array $Rule 118 | */ 119 | public static function getLists(User $user, string $list, array $opts, array $Rule) 120 | { 121 | $list = strtolower($list); 122 | if ($list == 'ssa') { 123 | $Rule['type'] = 'ss'; 124 | } 125 | if ($list == 'quantumult') { 126 | $Rule['type'] = 'vmess'; 127 | } 128 | if ($list == 'shadowrocket') { 129 | // Shadowrocket 自带 emoji 130 | $Rule['emoji'] = false; 131 | } 132 | $items = $user->getNew_AllItems($Rule); 133 | $return = []; 134 | if ($Rule['extend'] === true) { 135 | switch ($list) { 136 | case 'ssa': 137 | case 'clash': 138 | case 'clashr': 139 | $return = array_merge($return, self::getListExtend($user, $list)); 140 | break; 141 | default: 142 | $return[] = implode(PHP_EOL, self::getListExtend($user, $list)); 143 | break; 144 | } 145 | } 146 | foreach ($items as $item) { 147 | $out = self::getListItem($item, $list); 148 | if ($out != null) { 149 | $return[] = $out; 150 | } 151 | } 152 | switch ($list) { 153 | case 'ssa': 154 | return json_encode($return, 320); 155 | break; 156 | case 'clash': 157 | case 'clashr': 158 | return \Symfony\Component\Yaml\Yaml::dump(['proxies' => $return], 4, 2); 159 | case 'kitsunebi': 160 | case 'quantumult': 161 | case 'shadowrocket': 162 | return base64_encode(implode(PHP_EOL, $return)); 163 | default: 164 | return implode(PHP_EOL, $return); 165 | } 166 | } 167 | 168 | /** 169 | * Undocumented function 170 | * 171 | * @param User $user 172 | * @param string $list 173 | */ 174 | public static function getListExtend(User $user, string $list) 175 | { 176 | $return = []; 177 | $info_array = (count(Config::getInstance()->getConf('SUB.sub_message')) != 0 ? (array) Config::getInstance()->getConf('SUB.sub_message') : []); 178 | if (strtotime($user->expire_in) > time()) { 179 | if ($user->transfer_enable == 0) { 180 | $unusedTraffic = '剩余流量:0'; 181 | } else { 182 | $unusedTraffic = '剩余流量:' . $user->unusedTraffic(); 183 | } 184 | $expire_in = '过期时间:'; 185 | if ($user->class_expire != '1989-06-04 00:05:00') { 186 | $userClassExpire = explode(' ', $user->class_expire); 187 | $expire_in .= $userClassExpire[0]; 188 | } else { 189 | $expire_in .= '无限期'; 190 | } 191 | } else { 192 | $unusedTraffic = '账户已过期,请续费后使用'; 193 | $expire_in = '账户已过期,请续费后使用'; 194 | } 195 | if (!in_array($list, ['quantumult', 'quantumultx', 'shadowrocket'])) { 196 | $info_array[] = $unusedTraffic; 197 | $info_array[] = $expire_in; 198 | } 199 | $baseUrl = explode('//', Config::getInstance()->getConf('baseUrl'))[1]; 200 | $Extend = [ 201 | 'remark' => '', 202 | 'type' => '', 203 | 'add' => $baseUrl, 204 | 'address' => $baseUrl, 205 | 'port' => 10086, 206 | 'method' => 'chacha20-ietf', 207 | 'passwd' => $user->passwd, 208 | 'id' => $user->getUuid(), 209 | 'aid' => 0, 210 | 'net' => 'tcp', 211 | 'headerType' => 'none', 212 | 'host' => '', 213 | 'path' => '/', 214 | 'tls' => '', 215 | 'protocol' => 'origin', 216 | 'protocol_param' => '', 217 | 'obfs' => 'plain', 218 | 'obfs_param' => '', 219 | 'group' => Config::getInstance()->getConf('appName') 220 | ]; 221 | if ($list == 'shadowrocket') { 222 | $return[] = ('STATUS=' . $unusedTraffic . '.♥.' . $expire_in . PHP_EOL . 'REMARKS=' . Config::getInstance()->getConf('appName')); 223 | } 224 | foreach ($info_array as $remark) { 225 | $Extend['remark'] = $remark; 226 | if (in_array($list, ['kitsunebi', 'quantumult', 'v2rayn'])) { 227 | $Extend['type'] = 'vmess'; 228 | $out = self::getListItem($Extend, $list); 229 | } elseif ($list == 'trojan') { 230 | $Extend['type'] = 'trojan'; 231 | $out = self::getListItem($Extend, $list); 232 | } elseif ($list == 'ssr') { 233 | $Extend['type'] = 'ssr'; 234 | $out = self::getListItem($Extend, $list); 235 | } else { 236 | $Extend['type'] = 'ss'; 237 | $out = self::getListItem($Extend, $list); 238 | } 239 | if ($out !== null) $return[] = $out; 240 | } 241 | return $return; 242 | } 243 | 244 | /** 245 | * Surge 配置 246 | * 247 | * @param User $user 用户 248 | * @param int $surge 订阅类型 249 | * @param array $opts request 250 | * @param array $Rule 节点筛选规则 251 | */ 252 | public static function getSurge(User $user, int $surge, array $opts, array $Rule): string 253 | { 254 | $subInfo = self::getSubinfo($user, $surge); 255 | $userapiUrl = $subInfo['surge']; 256 | if ($surge != 4) { 257 | $Rule['type'] = 'ss'; 258 | } 259 | $items = $user->getNew_AllItems($Rule); 260 | $Nodes = []; 261 | $All_Proxy = ''; 262 | foreach ($items as $item) { 263 | $out = AppURI::getSurgeURI($item, $surge); 264 | if ($out !== null) { 265 | $Nodes[] = $item; 266 | $All_Proxy .= $out . PHP_EOL; 267 | } 268 | } 269 | $variable = ($surge == 2 ? 'Surge2_Profiles' : 'Surge_Profiles'); 270 | if (isset($opts['profiles']) && in_array($opts['profiles'], array_keys($_ENV[$variable]))) { 271 | $Profiles = $opts['profiles']; 272 | $userapiUrl .= ('&profiles=' . $Profiles); 273 | } else { 274 | $Profiles = ($surge == 2 ? Config::getInstance()->getConf('SUB.Surge2_DefaultProfiles') : Config::getInstance()->getConf('SUB.Surge_DefaultProfiles')); 275 | } 276 | 277 | return Conf::getSurgeConfs($user, $All_Proxy, $Nodes, $_ENV[$variable][$Profiles], $Rule['URL']); 278 | } 279 | 280 | /** 281 | * Quantumult 配置 282 | * 283 | * @param User $user 用户 284 | * @param int $quantumult 订阅类型 285 | * @param array $opts request 286 | * @param array $Rule 节点筛选规则 287 | */ 288 | public static function getQuantumult(User $user, int $quantumult, array $opts, array $Rule): string 289 | { 290 | switch ($quantumult) { 291 | case 2: 292 | $subUrl = self::getSubinfo($user, 0); 293 | $str = [ 294 | '[SERVER]', 295 | '', 296 | '[SOURCE]', 297 | Config::getInstance()->getConf('appName') . ', server ,' . $subUrl['ssr'] . ', false, true, false', 298 | Config::getInstance()->getConf('appName') . '_ss, server ,' . $subUrl['ss'] . ', false, true, false', 299 | Config::getInstance()->getConf('appName') . '_VMess, server ,' . $subUrl['quantumult_v2'] . ', false, true, false', 300 | 'Hackl0us Rules, filter, https://raw.githubusercontent.com/Hackl0us/Surge-Rule-Snippets/master/LAZY_RULES/Quantumult.conf, true', 301 | '', 302 | '[DNS]', 303 | 'system, 119.29.29.29, 223.6.6.6, 114.114.114.114', 304 | '', 305 | '[STATE]', 306 | 'STATE,AUTO' 307 | ]; 308 | return implode(PHP_EOL, $str); 309 | break; 310 | case 3: 311 | $items = $user->getNew_AllItems($Rule); 312 | break; 313 | default: 314 | return self::getLists($user, 'quantumult', $opts, $Rule); 315 | break; 316 | } 317 | 318 | $All_Proxy = ''; 319 | $All_Proxy_name = ''; 320 | $BackChina_name = ''; 321 | foreach ($items as $item) { 322 | $out = AppURI::getQuantumultURI($item); 323 | if ($out !== null) { 324 | $All_Proxy .= $out . PHP_EOL; 325 | if (strpos($item['remark'], '回国') || strpos($item['remark'], 'China')) { 326 | $BackChina_name .= "\n" . $item['remark']; 327 | } else { 328 | $All_Proxy_name .= "\n" . $item['remark']; 329 | } 330 | } 331 | } 332 | $conf = [ 333 | '[SERVER]', 334 | $All_Proxy, 335 | '', 336 | '[POLICY]', 337 | base64_encode("🍃 Proxy : static, 🏃 Auto\n🏃 Auto\n🚀 Direct\n" . $All_Proxy_name), 338 | base64_encode("🍂 Domestic : static, 🚀 Direct\n🚀 Direct\n🍃 Proxy\n" . $BackChina_name), 339 | base64_encode("☁️ Others : static, 🍃 Proxy\n🚀 Direct\n🍃 Proxy"), 340 | base64_encode("🚀 Direct : static, DIRECT\nDIRECT"), 341 | base64_encode("🍎 Only : static, 🚀 Direct\n🚀 Direct\n🍃 Proxy"), 342 | base64_encode("🏃 Auto : auto\n" . $All_Proxy_name), 343 | '', 344 | Conf::getRule(['source' => 'quantumult/quantumult.tpl']) 345 | ]; 346 | 347 | return implode(PHP_EOL, $conf); 348 | } 349 | 350 | /** 351 | * QuantumultX 配置 352 | * 353 | * @param User $user 用户 354 | * @param int $quantumultx 订阅类型 355 | * @param array $opts request 356 | * @param array $Rule 节点筛选规则 357 | */ 358 | public static function getQuantumultX(User $user, int $quantumultx, array $opts, array $Rule): string 359 | { 360 | return ''; 361 | } 362 | 363 | /** 364 | * Surfboard 配置 365 | * 366 | * @param User $user 用户 367 | * @param int $surfboard 订阅类型 368 | * @param array $opts request 369 | * @param array $Rule 节点筛选规则 370 | */ 371 | public static function getSurfboard(User $user, int $surfboard, array $opts, array $Rule): string 372 | { 373 | $subInfo = self::getSubinfo($user, 0); 374 | $userapiUrl = $subInfo['surfboard']; 375 | $Nodes = []; 376 | $All_Proxy = ''; 377 | $items = $user->getNew_AllItems($Rule); 378 | foreach ($items as $item) { 379 | $out = AppURI::getSurfboardURI($item); 380 | if ($out !== null) { 381 | $Nodes[] = $item; 382 | $All_Proxy .= $out . PHP_EOL; 383 | } 384 | } 385 | if (isset($opts['profiles']) && in_array($opts['profiles'], array_keys($_ENV['Surfboard_Profiles']))) { 386 | $Profiles = $opts['profiles']; 387 | $userapiUrl .= ('&profiles=' . $Profiles); 388 | } else { 389 | $Profiles = Config::getInstance()->getConf('SUB.Surfboard_DefaultProfiles'); // 默认策略组 390 | } 391 | 392 | return Conf::getSurgeConfs($user, $All_Proxy, $Nodes, $_ENV['Surfboard_Profiles'][$Profiles], $Rule['URL']); 393 | } 394 | 395 | /** 396 | * Clash 配置 397 | * 398 | * @param User $user 用户 399 | * @param int $clash 订阅类型 400 | * @param array $opts request 401 | * @param array $Rule 节点筛选规则 402 | */ 403 | public static function getClash(User $user, int $clash, array $opts, array $Rule): string 404 | { 405 | $subInfo = self::getSubinfo($user, $clash); 406 | $userapiUrl = $subInfo['clash']; 407 | $ssr_support = ($clash == 2 ? true : false); 408 | $items = $user->getNew_AllItems($Rule); 409 | $Proxys = []; 410 | foreach ($items as $item) { 411 | $Proxy = AppURI::getClashURI($item, $ssr_support); 412 | if ($Proxy !== null) { 413 | $Proxys[] = $Proxy; 414 | } 415 | } 416 | if (isset($opts['profiles']) && in_array($opts['profiles'], array_keys($_ENV['Clash_Profiles']))) { 417 | $Profiles = $opts['profiles']; 418 | $userapiUrl .= ('&profiles=' . $Profiles); 419 | } else { 420 | $Profiles = Config::getInstance()->getConf('SUB.Clash_DefaultProfiles'); // 默认策略组 421 | } 422 | 423 | return Conf::getClashConfs($user, $Proxys, $_ENV['Clash_Profiles'][$Profiles]); 424 | } 425 | 426 | /** 427 | * SSD 订阅 428 | * 429 | * @param User $user 用户 430 | * @param int $ssd 订阅类型 431 | * @param array $opts request 432 | * @param array $Rule 节点筛选规则 433 | */ 434 | public static function getSSD(User $user, int $ssd, array $opts, array $Rule):? string 435 | { 436 | if (!Tools::SSCanConnect($user)) { 437 | return null; 438 | } 439 | $array_all = []; 440 | $array_all['airport'] = Config::getInstance()->getConf('appName'); 441 | $array_all['port'] = $user->port; 442 | $array_all['encryption'] = $user->method; 443 | $array_all['password'] = $user->passwd; 444 | $array_all['traffic_used'] = Tools::flowToGB($user->u + $user->d); 445 | $array_all['traffic_total'] = Tools::flowToGB($user->transfer_enable); 446 | $array_all['expiry'] = $user->class_expire; 447 | $array_all['url'] = self::getSubinfo($user, 0)['ssd']; 448 | $plugin_options = ''; 449 | if (strpos($user->obfs, 'http') != false) { 450 | $plugin_options = 'obfs=http'; 451 | } 452 | if (strpos($user->obfs, 'tls') != false) { 453 | $plugin_options = 'obfs=tls'; 454 | } 455 | if ($plugin_options != '') { 456 | $array_all['plugin'] = 'simple-obfs'; 457 | $array_all['plugin_options'] = $plugin_options; 458 | if ($user->obfs_param != '') { 459 | $array_all['plugin_options'] .= ';obfs-host=' . $user->obfs_param; 460 | } 461 | } 462 | $array_server = []; 463 | $server_index = 1; 464 | $Rule['type'] = 'ss'; 465 | $nodes = $user->getNew_AllItems($Rule); 466 | foreach ($nodes as $item) { 467 | if ($item['type'] != 'ss') continue; 468 | $server = AppURI::getSSDURI($item); 469 | if ($server !== null) { 470 | $server['id'] = $server_index; 471 | $array_server[] = $server; 472 | $server_index++; 473 | } 474 | } 475 | $array_all['servers'] = $array_server; 476 | $json_all = json_encode($array_all, 320); 477 | 478 | return 'ssd://' . base64_encode($json_all); 479 | } 480 | 481 | /** 482 | * 通用订阅,ssr & v2rayn 483 | * 484 | * @param User $user 用户 485 | * @param int $sub 订阅类型 486 | * @param array $opts request 487 | * @param array $Rule 节点筛选规则 488 | */ 489 | public static function getSub(User $user, int $sub, array $opts, array $Rule): string 490 | { 491 | $return_url = ''; 492 | switch ($sub) { 493 | case 2: // SS 494 | $Rule['type'] = 'ss'; 495 | $getListExtend = $Rule['extend'] ? self::getListExtend($user, 'ss') : []; 496 | break; 497 | case 3: // V2 498 | $Rule['type'] = 'vmess'; 499 | $getListExtend = $Rule['extend'] ? self::getListExtend($user, 'v2rayn') : []; 500 | break; 501 | case 4: // Trojan 502 | $Rule['type'] = 'trojan'; 503 | $getListExtend = $Rule['extend'] ? self::getListExtend($user, 'trojan') : []; 504 | break; 505 | default: // SSR 506 | $Rule['type'] = 'ssr'; 507 | $getListExtend = $Rule['extend'] ? self::getListExtend($user, 'ssr') : []; 508 | break; 509 | } 510 | if ($Rule['extend']) { 511 | $return_url .= implode(PHP_EOL, $getListExtend) . PHP_EOL; 512 | } 513 | $return_url .= $user->get_NewAllUrl($Rule); 514 | return base64_encode($return_url); 515 | } 516 | } 517 | -------------------------------------------------------------------------------- /App/Utils/Tools.php: -------------------------------------------------------------------------------- 1 | where('is_multi_user', '<>', 0)->first(); 203 | if ($mu_user == null) { 204 | return false; 205 | } 206 | return self::SSCanConnect($mu_user); 207 | } 208 | return self::CanMethodConnect($user->method) >= 2 && self::CanProtocolConnect($user->protocol) >= 2 && self::CanObfsConnect($user->obfs) >= 2; 209 | } 210 | 211 | /** 212 | * 检测用户是否可连接 SSR 213 | * 214 | * @param User $user 215 | * @param int $mu_port 216 | */ 217 | public static function SSRCanConnect($user, $mu_port = 0): bool 218 | { 219 | if ($mu_port != 0) { 220 | $mu_user = User::where('port', '=', $mu_port)->where('is_multi_user', '<>', 0)->first(); 221 | if ($mu_user == null) { 222 | return false; 223 | } 224 | return self::SSRCanConnect($mu_user); 225 | } 226 | return self::CanMethodConnect($user->method) != 2 && self::CanProtocolConnect($user->protocol) != 2 && self::CanObfsConnect($user->obfs) != 2; 227 | } 228 | 229 | /** 230 | * 获取用户的 SS 连接信息 231 | * 232 | * @param User $user 233 | */ 234 | public static function getSSConnectInfo($user): User 235 | { 236 | $new_user = clone $user; 237 | if (self::CanObfsConnect($new_user->obfs) == 5) { 238 | $new_user->obfs = 'plain'; 239 | $new_user->obfs_param = ''; 240 | } 241 | if (self::CanProtocolConnect($new_user->protocol) == 3) { 242 | $new_user->protocol = 'origin'; 243 | $new_user->protocol_param = ''; 244 | } 245 | $new_user->obfs = str_replace('_compatible', '', $new_user->obfs); 246 | $new_user->protocol = str_replace('_compatible', '', $new_user->protocol); 247 | return $new_user; 248 | } 249 | 250 | /** 251 | * 获取用户的 SSR 连接信息 252 | * 253 | * @param User $user 254 | */ 255 | public static function getSSRConnectInfo($user): User 256 | { 257 | $new_user = clone $user; 258 | if (self::CanObfsConnect($new_user->obfs) == 4) { 259 | $new_user->obfs = 'plain'; 260 | $new_user->obfs_param = ''; 261 | } 262 | $new_user->obfs = str_replace('_compatible', '', $new_user->obfs); 263 | $new_user->protocol = str_replace('_compatible', '', $new_user->protocol); 264 | return $new_user; 265 | } 266 | 267 | public static function parse_args($origin) 268 | { 269 | // parse xxx=xxx|xxx=xxx to array(xxx => xxx, xxx => xxx) 270 | $args_explode = explode('|', $origin); 271 | $return_array = []; 272 | foreach ($args_explode as $arg) { 273 | $split_point = strpos($arg, '='); 274 | 275 | $return_array[substr($arg, 0, $split_point)] = substr($arg, $split_point + 1); 276 | } 277 | return $return_array; 278 | } 279 | 280 | /** 281 | * @param $traffic 282 | * @return float 283 | */ 284 | public static function flowToGB($traffic) 285 | { 286 | $gb = 1048576 * 1024; 287 | return $traffic / $gb; 288 | } 289 | 290 | public static function base64_url_encode($input) 291 | { 292 | return strtr(base64_encode($input), array('+' => '-', '/' => '_', '=' => '')); 293 | } 294 | 295 | public static function base64_url_decode($input) 296 | { 297 | return base64_decode(strtr($input, '-_', '+/')); 298 | } 299 | 300 | public static function pick_out_relay_rule($relay_node_id, $port, $ruleset) 301 | { 302 | $match_rule = null; 303 | foreach ($ruleset as $single_rule) { 304 | if (($single_rule->port == $port || $single_rule->port == 0) && ($single_rule->source_node_id == 0 || $single_rule->source_node_id == $relay_node_id)) { 305 | $has_higher_priority = false; 306 | foreach ($ruleset as $priority_rule) { 307 | if (($priority_rule->port == $port || $priority_rule->port == 0) && ($priority_rule->source_node_id == 0 || $priority_rule->source_node_id == $relay_node_id)) { 308 | if (($priority_rule->priority > $single_rule->priority && $priority_rule->id != $single_rule->id) || ($priority_rule->priority == $single_rule->priority && $priority_rule->id < $single_rule->id)) { 309 | $has_higher_priority = true; 310 | continue; 311 | } 312 | } 313 | } 314 | if ($has_higher_priority) { 315 | continue; 316 | } 317 | $match_rule = $single_rule; 318 | } 319 | } 320 | if (($match_rule != null) && $match_rule->dist_node_id == -1) { 321 | return null; 322 | } 323 | return $match_rule; 324 | } 325 | 326 | public static function is_protocol_relay($user) 327 | { 328 | return true; 329 | 330 | $relay_able_list = self::getSupportParam('relay_able_protocol'); 331 | 332 | return in_array($user->protocol, $relay_able_list) || Config::getInstance()->getConf('relay_insecure_mode') == true; 333 | } 334 | 335 | public static function v2Array($node) 336 | { 337 | $server = explode(';', $node); 338 | $item = [ 339 | 'host' => '', 340 | 'path' => '', 341 | 'tls' => '', 342 | 'verify_cert' => true 343 | ]; 344 | $item['add'] = $server[0]; 345 | if ($server[1] == '0' || $server[1] == '') { 346 | $item['port'] = 443; 347 | } else { 348 | $item['port'] = (int) $server[1]; 349 | } 350 | $item['aid'] = (int) $server[2]; 351 | $item['net'] = 'tcp'; 352 | $item['headerType'] = 'none'; 353 | if (count($server) >= 4) { 354 | $item['net'] = $server[3]; 355 | if ($item['net'] == 'ws') { 356 | $item['path'] = '/'; 357 | } elseif ($item['net'] == 'tls') { 358 | $item['tls'] = 'tls'; 359 | } 360 | } 361 | if (count($server) >= 5) { 362 | if (in_array($item['net'], array('kcp', 'http', 'mkcp'))) { 363 | $item['headerType'] = $server[4]; 364 | } elseif ($server[4] == 'ws') { 365 | $item['net'] = 'ws'; 366 | } elseif ($server[4] == 'tls') { 367 | $item['tls'] = 'tls'; 368 | } 369 | } 370 | if (count($server) >= 6 && $server[5] != '') { 371 | $item = array_merge($item, self::parse_args($server[5])); 372 | if (array_key_exists('server', $item)) { 373 | $item['add'] = $item['server']; 374 | unset($item['server']); 375 | } 376 | if (array_key_exists('relayserver', $item)) { 377 | $item['localserver'] = $item['add']; 378 | $item['add'] = $item['relayserver']; 379 | unset($item['relayserver']); 380 | if ($item['tls'] == 'tls') { 381 | $item['verify_cert'] = false; 382 | } 383 | } 384 | if (array_key_exists('outside_port', $item)) { 385 | $item['port'] = (int) $item['outside_port']; 386 | unset($item['outside_port']); 387 | } 388 | if (isset($item['inside_port'])) { 389 | unset($item['inside_port']); 390 | } 391 | } 392 | return $item; 393 | } 394 | 395 | public static function ssv2Array($node) 396 | { 397 | $server = explode(';', $node); 398 | $item = [ 399 | 'host' => 'microsoft.com', 400 | 'path' => '', 401 | 'net' => 'ws', 402 | 'tls' => '' 403 | ]; 404 | $item['add'] = $server[0]; 405 | if ($server[1] == '0' || $server[1] == '') { 406 | $item['port'] = 443; 407 | } else { 408 | $item['port'] = (int) $server[1]; 409 | } 410 | if (count($server) >= 4) { 411 | $item['net'] = $server[3]; 412 | if ($item['net'] == 'ws') { 413 | $item['path'] = '/'; 414 | } elseif ($item['net'] == 'tls') { 415 | $item['tls'] = 'tls'; 416 | } 417 | } 418 | if (count($server) >= 5 && $server[4] == 'ws') { 419 | $item['net'] = 'ws'; 420 | } elseif (count($server) >= 5 && $server[4] == 'tls') { 421 | $item['tls'] = 'tls'; 422 | } 423 | if (count($server) >= 6) { 424 | $item = array_merge($item, self::parse_args($server[5])); 425 | if (array_key_exists('server', $item)) { 426 | $item['add'] = $item['server']; 427 | unset($item['server']); 428 | } 429 | if (array_key_exists('relayserver', $item)) { 430 | $item['add'] = $item['relayserver']; 431 | unset($item['relayserver']); 432 | } 433 | if (array_key_exists('outside_port', $item)) { 434 | $item['port'] = (int) $item['outside_port']; 435 | unset($item['outside_port']); 436 | } 437 | } 438 | if ($item['net'] == 'obfs') { 439 | if (stripos($server[4], 'http') !== false) { 440 | $item['obfs'] = 'simple_obfs_http'; 441 | } 442 | if (stripos($server[4], 'tls') !== false) { 443 | $item['obfs'] = 'simple_obfs_tls'; 444 | } 445 | } 446 | return $item; 447 | } 448 | 449 | public static function OutPort($server, $node_name, $mu_port) 450 | { 451 | $node_server = explode(';', $server); 452 | $node_port = $mu_port; 453 | 454 | if (isset($node_server[1])) { 455 | if (strpos($node_server[1], 'port') !== false) { 456 | $item = self::parse_args($node_server[1]); 457 | if (strpos($item['port'], '#') !== false) { // 端口偏移,指定端口,格式:8.8.8.8;port=80#1080 458 | if (strpos($item['port'], '+') !== false) { // 多个单端口节点,格式:8.8.8.8;port=80#1080+443#8443 459 | $args_explode = explode('+', $item['port']); 460 | foreach ($args_explode as $arg) { 461 | if ((int) substr($arg, 0, strpos($arg, '#')) == $mu_port) { 462 | $node_port = (int) substr($arg, strpos($arg, '#') + 1); 463 | } 464 | } 465 | } else { 466 | if ((int) substr($item['port'], 0, strpos($item['port'], '#')) == $mu_port) { 467 | $node_port = (int) substr($item['port'], strpos($item['port'], '#') + 1); 468 | } 469 | } 470 | } else { // 端口偏移,偏移端口,格式:8.8.8.8;port=1000 or 8.8.8.8;port=-1000 471 | $node_port = ($mu_port + (int) $item['port']); 472 | } 473 | } 474 | } 475 | 476 | return [ 477 | 'name' => (Config::getInstance()->getConf('SUB.disable_sub_mu_port') ? $node_name : $node_name . ' - ' . $node_port . ' 单端口'), 478 | 'address' => $node_server[0], 479 | 'port' => $node_port 480 | ]; 481 | } 482 | 483 | public static function get_MuOutPortArray($server) 484 | { 485 | $type = 0; //偏移 486 | $port = []; //指定 487 | $node_server = explode(';', $server); 488 | if (isset($node_server[1])) { 489 | if (strpos($node_server[1], 'port') !== false) { 490 | $item = self::parse_args($node_server[1]); 491 | if (strpos($item['port'], '#') !== false) { 492 | if (strpos($item['port'], '+') !== false) { 493 | $args_explode = explode('+', $item['port']); 494 | foreach ($args_explode as $arg) { 495 | $port[substr($arg, 0, strpos($arg, '#'))] = (int) substr($arg, strpos($arg, '#') + 1); 496 | } 497 | } else { 498 | $port[substr($item['port'], 0, strpos($item['port'], '#'))] = (int) substr($item['port'], strpos($item['port'], '#') + 1); 499 | } 500 | } else { 501 | $type = (int) $item['port']; 502 | } 503 | } 504 | } 505 | 506 | return [ 507 | 'type' => $type, 508 | 'port' => $port 509 | ]; 510 | } 511 | 512 | // 请将冷门的国家或地区放置在上方,热门的中继起源放置在下方 513 | // 以便于兼容如:【上海 -> 美国】等节点名称 514 | private static $emoji = [ 515 | "🇦🇷" => [ 516 | "阿根廷" 517 | ], 518 | "🇦🇹" => [ 519 | "奥地利", 520 | "维也纳" 521 | ], 522 | "🇦🇺" => [ 523 | "澳大利亚", 524 | "悉尼" 525 | ], 526 | "🇧🇷" => [ 527 | "巴西", 528 | "圣保罗" 529 | ], 530 | "🇨🇦" => [ 531 | "加拿大", 532 | "蒙特利尔", 533 | "温哥华" 534 | ], 535 | "🇨🇭" => [ 536 | "瑞士", 537 | "苏黎世" 538 | ], 539 | "🇩🇪" => [ 540 | "德国", 541 | "法兰克福" 542 | ], 543 | "🇫🇮" => [ 544 | "芬兰", 545 | "赫尔辛基" 546 | ], 547 | "🇫🇷" => [ 548 | "法国", 549 | "巴黎" 550 | ], 551 | "🇬🇧" => [ 552 | "英国", 553 | "伦敦" 554 | ], 555 | "🇮🇩" => [ 556 | "印尼", 557 | "印度尼西亚", 558 | "雅加达" 559 | ], 560 | "🇮🇪" => [ 561 | "爱尔兰", 562 | "都柏林" 563 | ], 564 | "🇮🇳" => [ 565 | "印度", 566 | "孟买" 567 | ], 568 | "🇮🇹" => [ 569 | "意大利", 570 | "米兰" 571 | ], 572 | "🇰🇵" => [ 573 | "朝鲜" 574 | ], 575 | "🇲🇾" => [ 576 | "马来西亚" 577 | ], 578 | "🇳🇱" => [ 579 | "荷兰", 580 | "阿姆斯特丹" 581 | ], 582 | "🇵🇭" => [ 583 | "菲律宾" 584 | ], 585 | "🇷🇴" => [ 586 | "罗马尼亚" 587 | ], 588 | "🇷🇺" => [ 589 | "俄罗斯", 590 | "伯力", 591 | "莫斯科", 592 | "圣彼得堡", 593 | "西伯利亚", 594 | "新西伯利亚" 595 | ], 596 | "🇸🇬" => [ 597 | "新加坡" 598 | ], 599 | "🇹🇭" => [ 600 | "泰国", 601 | "曼谷" 602 | ], 603 | "🇹🇷" => [ 604 | "土耳其", 605 | "伊斯坦布尔" 606 | ], 607 | "🇺🇲" => [ 608 | "美国", 609 | "波特兰", 610 | "俄勒冈", 611 | "凤凰城", 612 | "费利蒙", 613 | "硅谷", 614 | "拉斯维加斯", 615 | "洛杉矶", 616 | "圣克拉拉", 617 | "西雅图", 618 | "芝加哥", 619 | "沪美" 620 | ], 621 | "🇻🇳" => [ 622 | "越南" 623 | ], 624 | "🇿🇦" => [ 625 | "南非" 626 | ], 627 | "🇰🇷" => [ 628 | "韩国", 629 | "首尔" 630 | ], 631 | "🇲🇴" => [ 632 | "澳门" 633 | ], 634 | "🇯🇵" => [ 635 | "日本", 636 | "东京", 637 | "大阪", 638 | "埼玉", 639 | "沪日" 640 | ], 641 | "🇹🇼" => [ 642 | "台湾", 643 | "台北", 644 | "台中" 645 | ], 646 | "🇭🇰" => [ 647 | "香港", 648 | "深港" 649 | ], 650 | "🇨🇳" => [ 651 | "中国", 652 | "江苏", 653 | "北京", 654 | "上海", 655 | "深圳", 656 | "杭州", 657 | "徐州", 658 | "宁波", 659 | "镇江" 660 | ] 661 | ]; 662 | 663 | public static function addEmoji($Name) 664 | { 665 | $done = [ 666 | 'index' => -1, 667 | 'emoji' => '' 668 | ]; 669 | foreach (self::$emoji as $key => $value) { 670 | foreach ($value as $item) { 671 | $index = strpos($Name, $item); 672 | if ($index !== false) { 673 | $done['index'] = $index; 674 | $done['emoji'] = $key; 675 | continue 2; 676 | } 677 | } 678 | } 679 | return ($done['index'] == -1 680 | ? $Name 681 | : ($done['emoji'] . ' ' . $Name)); 682 | } 683 | 684 | /** 685 | * 根据流量值自动转换单位输出 686 | */ 687 | public static function flowAutoShow($value = 0) 688 | { 689 | $kb = 1024; 690 | $mb = 1048576; 691 | $gb = 1073741824; 692 | $tb = $gb * 1024; 693 | $pb = $tb * 1024; 694 | if (abs($value) > $pb) { 695 | return round($value / $pb, 2) . 'PB'; 696 | } 697 | if (abs($value) > $tb) { 698 | return round($value / $tb, 2) . 'TB'; 699 | } 700 | if (abs($value) > $gb) { 701 | return round($value / $gb, 2) . 'GB'; 702 | } 703 | if (abs($value) > $mb) { 704 | return round($value / $mb, 2) . 'MB'; 705 | } 706 | if (abs($value) > $kb) { 707 | return round($value / $kb, 2) . 'KB'; 708 | } 709 | return round($value, 2) . 'B'; 710 | } 711 | } 712 | -------------------------------------------------------------------------------- /EasySwooleEvent.php: -------------------------------------------------------------------------------- 1 | getConf('database'); 22 | $capsule = new Capsule; 23 | // 创建链接 24 | $capsule->addConnection($dbConf); 25 | // 设置全局静态可访问 26 | $capsule->setAsGlobal(); 27 | // 启动Eloquent 28 | $capsule->bootEloquent(); 29 | } 30 | 31 | public static function mainServerCreate(EventRegister $register) 32 | { 33 | // TODO: Implement mainServerCreate() method. 34 | } 35 | 36 | public static function onRequest(Request $request, Response $response): bool 37 | { 38 | // TODO: Implement onRequest() method. 39 | return true; 40 | } 41 | 42 | public static function afterRequest(Request $request, Response $response): void 43 | { 44 | // TODO: Implement afterAction() method. 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Log/log_DEBUG.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekQuerxy/SSPanelSubcribe/d387a25c57b08bd8717f1740f3e60c2fb0fa6306/Log/log_DEBUG.log -------------------------------------------------------------------------------- /Log/swoole.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekQuerxy/SSPanelSubcribe/d387a25c57b08bd8717f1740f3e60c2fb0fa6306/Log/swoole.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # geekSubcribeX 3 | 4 | ## 简介 5 | 6 | 使用 EasySwoole 开发的适用于 SSPanel-Uim 的独立订阅服务提供 7 | 8 | ## 使用 9 | 10 | - 将 `config.php` 重命名为 [生产] `produce.php` 或 [测试] `dev.php` 11 | - 将 `appprofile.example.php` 重命名为 `appprofile.php` 12 | 13 | [请查看 EasySwoole 服务管理进行使用](https://www.easyswoole.com/Cn/QuickStart/server.html) 14 | 15 | ## 其他 16 | 17 | 项目测试阶段,issue 已开放 18 | -------------------------------------------------------------------------------- /Resources/Conf/surfboard/default.tpl: -------------------------------------------------------------------------------- 1 | PROCESS-NAME,aria2c,DIRECT 2 | PROCESS-NAME,fdm,DIRECT 3 | PROCESS-NAME,Folx,DIRECT 4 | PROCESS-NAME,NetTransport,DIRECT 5 | PROCESS-NAME,Thunder,DIRECT 6 | PROCESS-NAME,Transmission,DIRECT 7 | PROCESS-NAME,uTorrent,DIRECT 8 | PROCESS-NAME,WebTorrent,DIRECT 9 | PROCESS-NAME,WebTorrent Helper,DIRECT 10 | DOMAIN-SUFFIX,smtp,DIRECT 11 | DOMAIN-KEYWORD,aria2,DIRECT 12 | URL-REGEX,(Subject|HELO|SMTP),DIRECT 13 | URL-REGEX,(api|ps|sv|offnavi|newvector|ulog.imap|newloc)(.map|).(baidu|n.shifen).com,DIRECT 14 | URL-REGEX,(.+.|^)(360|so|qihoo|360safe|qhimg|360totalsecurity|yunpan).(cn|com),DIRECT 15 | URL-REGEX,(.+.)?(torrent|announce.php?passkey=|tracker|BitTorrent|bt_key|ed2k|find_node|get_peers|info_hash|magnet:|peer_id=|xunlei)(..+)?,DIRECT 16 | URL-REGEX,(.?)(xunlei|sandai|Thunder|XLLiveUD)(.),DIRECT 17 | PROCESS-NAME,DownloadService,DIRECT 18 | URL-REGEX,(.+\.|^)(360|so)\.(cn|com),DIRECT 19 | PROCESS-NAME,Weiyun,DIRECT 20 | 21 | DOMAIN-SUFFIX,ampproject.org,🔰国外流量 22 | DOMAIN-SUFFIX,appspot.com,🔰国外流量 23 | DOMAIN-SUFFIX,blogger.com,🔰国外流量 24 | DOMAIN-SUFFIX,getoutline.org,🔰国外流量 25 | DOMAIN-SUFFIX,gvt0.com,🔰国外流量 26 | DOMAIN-SUFFIX,gvt1.com,🔰国外流量 27 | DOMAIN-SUFFIX,gvt3.com,🔰国外流量 28 | DOMAIN-SUFFIX,xn--ngstr-lra8j.com,🔰国外流量 29 | DOMAIN-KEYWORD,google,🔰国外流量 30 | DOMAIN-KEYWORD,blogspot,🔰国外流量 31 | DOMAIN-SUFFIX,onedrive.live.com,🔰国外流量 32 | DOMAIN-SUFFIX,xboxlive.com,🔰国外流量 33 | DOMAIN-SUFFIX,cdninstagram.com,🔰国外流量 34 | DOMAIN-SUFFIX,fb.com,🔰国外流量 35 | DOMAIN-SUFFIX,fb.me,🔰国外流量 36 | DOMAIN-SUFFIX,fbaddins.com,🔰国外流量 37 | DOMAIN-SUFFIX,fbcdn.net,🔰国外流量 38 | DOMAIN-SUFFIX,fbsbx.com,🔰国外流量 39 | DOMAIN-SUFFIX,fbworkmail.com,🔰国外流量 40 | DOMAIN-SUFFIX,instagram.com,🔰国外流量 41 | DOMAIN-SUFFIX,m.me,🔰国外流量 42 | DOMAIN-SUFFIX,messenger.com,🔰国外流量 43 | DOMAIN-SUFFIX,oculus.com,🔰国外流量 44 | DOMAIN-SUFFIX,oculuscdn.com,🔰国外流量 45 | DOMAIN-SUFFIX,rocksdb.org,🔰国外流量 46 | DOMAIN-SUFFIX,whatsapp.com,🔰国外流量 47 | DOMAIN-SUFFIX,whatsapp.net,🔰国外流量 48 | DOMAIN-KEYWORD,facebook,🔰国外流量 49 | IP-CIDR,3.123.36.126/32,🔰国外流量,no-resolve 50 | IP-CIDR,35.157.215.84/32,🔰国外流量,no-resolve 51 | IP-CIDR,35.157.217.255/32,🔰国外流量,no-resolve 52 | IP-CIDR,52.58.209.134/32,🔰国外流量,no-resolve 53 | IP-CIDR,54.93.124.31/32,🔰国外流量,no-resolve 54 | IP-CIDR,54.162.243.80/32,🔰国外流量,no-resolve 55 | IP-CIDR,54.173.34.141/32,🔰国外流量,no-resolve 56 | IP-CIDR,54.235.23.242/32,🔰国外流量,no-resolve 57 | IP-CIDR,169.45.248.118/32,🔰国外流量,no-resolve 58 | DOMAIN-SUFFIX,pscp.tv,🔰国外流量 59 | DOMAIN-SUFFIX,periscope.tv,🔰国外流量 60 | DOMAIN-SUFFIX,t.co,🔰国外流量 61 | DOMAIN-SUFFIX,twimg.co,🔰国外流量 62 | DOMAIN-SUFFIX,twimg.com,🔰国外流量 63 | DOMAIN-SUFFIX,twitpic.com,🔰国外流量 64 | DOMAIN-SUFFIX,vine.co,🔰国外流量 65 | DOMAIN-KEYWORD,twitter,🔰国外流量 66 | DOMAIN-SUFFIX,t.me,🔰国外流量 67 | DOMAIN-SUFFIX,tdesktop.com,🔰国外流量 68 | DOMAIN-SUFFIX,telegra.ph,🔰国外流量 69 | DOMAIN-SUFFIX,telegram.me,🔰国外流量 70 | DOMAIN-SUFFIX,telegram.org,🔰国外流量 71 | IP-CIDR,91.108.4.0/22,🔰国外流量,no-resolve 72 | IP-CIDR,91.108.8.0/22,🔰国外流量,no-resolve 73 | IP-CIDR,91.108.12.0/22,🔰国外流量,no-resolve 74 | IP-CIDR,91.108.16.0/22,🔰国外流量,no-resolve 75 | IP-CIDR,91.108.56.0/22,🔰国外流量,no-resolve 76 | IP-CIDR,149.154.160.0/20,🔰国外流量,no-resolve 77 | IP-CIDR6,2001:b28:f23d::/48,🔰国外流量,no-resolve 78 | IP-CIDR6,2001:b28:f23f::/48,🔰国外流量,no-resolve 79 | IP-CIDR6,2001:67c:4e8::/48,🔰国外流量,no-resolve 80 | DOMAIN-SUFFIX,line.me,🔰国外流量 81 | DOMAIN-SUFFIX,line-apps.com,🔰国外流量 82 | DOMAIN-SUFFIX,line-scdn.net,🔰国外流量 83 | DOMAIN-SUFFIX,naver.jp,🔰国外流量 84 | IP-CIDR,103.2.30.0/23,🔰国外流量,no-resolve 85 | IP-CIDR,125.209.208.0/20,🔰国外流量,no-resolve 86 | IP-CIDR,147.92.128.0/17,🔰国外流量,no-resolve 87 | IP-CIDR,203.104.144.0/21,🔰国外流量,no-resolve 88 | DOMAIN-SUFFIX,4shared.com,🔰国外流量 89 | DOMAIN-SUFFIX,520cc.cc,🔰国外流量 90 | DOMAIN-SUFFIX,881903.com,🔰国外流量 91 | DOMAIN-SUFFIX,9cache.com,🔰国外流量 92 | DOMAIN-SUFFIX,9gag.com,🔰国外流量 93 | DOMAIN-SUFFIX,abc.com,🔰国外流量 94 | DOMAIN-SUFFIX,abc.net.au,🔰国外流量 95 | DOMAIN-SUFFIX,abebooks.com,🔰国外流量 96 | DOMAIN-SUFFIX,amazon.co.jp,🔰国外流量 97 | DOMAIN-SUFFIX,apigee.com,🔰国外流量 98 | DOMAIN-SUFFIX,apk-dl.com,🔰国外流量 99 | DOMAIN-SUFFIX,apkfind.com,🔰国外流量 100 | DOMAIN-SUFFIX,apkmirror.com,🔰国外流量 101 | DOMAIN-SUFFIX,apkmonk.com,🔰国外流量 102 | DOMAIN-SUFFIX,apkpure.com,🔰国外流量 103 | DOMAIN-SUFFIX,aptoide.com,🔰国外流量 104 | DOMAIN-SUFFIX,archive.is,🔰国外流量 105 | DOMAIN-SUFFIX,archive.org,🔰国外流量 106 | DOMAIN-SUFFIX,arte.tv,🔰国外流量 107 | DOMAIN-SUFFIX,artstation.com,🔰国外流量 108 | DOMAIN-SUFFIX,arukas.io,🔰国外流量 109 | DOMAIN-SUFFIX,ask.com,🔰国外流量 110 | DOMAIN-SUFFIX,avg.com,🔰国外流量 111 | DOMAIN-SUFFIX,avgle.com,🔰国外流量 112 | DOMAIN-SUFFIX,badoo.com,🔰国外流量 113 | DOMAIN-SUFFIX,bandwagonhost.com,🔰国外流量 114 | DOMAIN-SUFFIX,bbc.com,🔰国外流量 115 | DOMAIN-SUFFIX,behance.net,🔰国外流量 116 | DOMAIN-SUFFIX,bibox.com,🔰国外流量 117 | DOMAIN-SUFFIX,biggo.com.tw,🔰国外流量 118 | DOMAIN-SUFFIX,binance.com,🔰国外流量 119 | DOMAIN-SUFFIX,bitcointalk.org,🔰国外流量 120 | DOMAIN-SUFFIX,bitfinex.com,🔰国外流量 121 | DOMAIN-SUFFIX,bitmex.com,🔰国外流量 122 | DOMAIN-SUFFIX,bit-z.com,🔰国外流量 123 | DOMAIN-SUFFIX,bloglovin.com,🔰国外流量 124 | DOMAIN-SUFFIX,bloomberg.cn,🔰国外流量 125 | DOMAIN-SUFFIX,bloomberg.com,🔰国外流量 126 | DOMAIN-SUFFIX,blubrry.com,🔰国外流量 127 | DOMAIN-SUFFIX,book.com.tw,🔰国外流量 128 | DOMAIN-SUFFIX,booklive.jp,🔰国外流量 129 | DOMAIN-SUFFIX,books.com.tw,🔰国外流量 130 | DOMAIN-SUFFIX,boslife.net,🔰国外流量 131 | DOMAIN-SUFFIX,box.com,🔰国外流量 132 | DOMAIN-SUFFIX,businessinsider.com,🔰国外流量 133 | DOMAIN-SUFFIX,bwh1.net,🔰国外流量 134 | DOMAIN-SUFFIX,castbox.fm,🔰国外流量 135 | DOMAIN-SUFFIX,cbc.ca,🔰国外流量 136 | DOMAIN-SUFFIX,cdw.com,🔰国外流量 137 | DOMAIN-SUFFIX,change.org,🔰国外流量 138 | DOMAIN-SUFFIX,channelnewsasia.com,🔰国外流量 139 | DOMAIN-SUFFIX,ck101.com,🔰国外流量 140 | DOMAIN-SUFFIX,clarionproject.org,🔰国外流量 141 | DOMAIN-SUFFIX,clyp.it,🔰国外流量 142 | DOMAIN-SUFFIX,cna.com.tw,🔰国外流量 143 | DOMAIN-SUFFIX,comparitech.com,🔰国外流量 144 | DOMAIN-SUFFIX,conoha.jp,🔰国外流量 145 | DOMAIN-SUFFIX,crucial.com,🔰国外流量 146 | DOMAIN-SUFFIX,cts.com.tw,🔰国外流量 147 | DOMAIN-SUFFIX,cw.com.tw,🔰国外流量 148 | DOMAIN-SUFFIX,cyberctm.com,🔰国外流量 149 | DOMAIN-SUFFIX,dailymotion.com,🔰国外流量 150 | DOMAIN-SUFFIX,dailyview.tw,🔰国外流量 151 | DOMAIN-SUFFIX,daum.net,🔰国外流量 152 | DOMAIN-SUFFIX,daumcdn.net,🔰国外流量 153 | DOMAIN-SUFFIX,dcard.tw,🔰国外流量 154 | DOMAIN-SUFFIX,deepdiscount.com,🔰国外流量 155 | DOMAIN-SUFFIX,depositphotos.com,🔰国外流量 156 | DOMAIN-SUFFIX,deviantart.com,🔰国外流量 157 | DOMAIN-SUFFIX,disconnect.me,🔰国外流量 158 | DOMAIN-SUFFIX,discordapp.com,🔰国外流量 159 | DOMAIN-SUFFIX,discordapp.net,🔰国外流量 160 | DOMAIN-SUFFIX,disqus.com,🔰国外流量 161 | DOMAIN-SUFFIX,dlercloud.com,🔰国外流量 162 | DOMAIN-SUFFIX,dns2go.com,🔰国外流量 163 | DOMAIN-SUFFIX,dowjones.com,🔰国外流量 164 | DOMAIN-SUFFIX,dropbox.com,🔰国外流量 165 | DOMAIN-SUFFIX,dropboxusercontent.com,🔰国外流量 166 | DOMAIN-SUFFIX,duckduckgo.com,🔰国外流量 167 | DOMAIN-SUFFIX,dw.com,🔰国外流量 168 | DOMAIN-SUFFIX,dynu.com,🔰国外流量 169 | DOMAIN-SUFFIX,earthcam.com,🔰国外流量 170 | DOMAIN-SUFFIX,ebookservice.tw,🔰国外流量 171 | DOMAIN-SUFFIX,economist.com,🔰国外流量 172 | DOMAIN-SUFFIX,edgecastcdn.net,🔰国外流量 173 | DOMAIN-SUFFIX,edu,🔰国外流量 174 | DOMAIN-SUFFIX,elpais.com,🔰国外流量 175 | DOMAIN-SUFFIX,enanyang.my,🔰国外流量 176 | DOMAIN-SUFFIX,encyclopedia.com,🔰国外流量 177 | DOMAIN-SUFFIX,esoir.be,🔰国外流量 178 | DOMAIN-SUFFIX,etherscan.io,🔰国外流量 179 | DOMAIN-SUFFIX,euronews.com,🔰国外流量 180 | DOMAIN-SUFFIX,evozi.com,🔰国外流量 181 | DOMAIN-SUFFIX,feedly.com,🔰国外流量 182 | DOMAIN-SUFFIX,firech.at,🔰国外流量 183 | DOMAIN-SUFFIX,flickr.com,🔰国外流量 184 | DOMAIN-SUFFIX,flitto.com,🔰国外流量 185 | DOMAIN-SUFFIX,foreignpolicy.com,🔰国外流量 186 | DOMAIN-SUFFIX,freebrowser.org,🔰国外流量 187 | DOMAIN-SUFFIX,freewechat.com,🔰国外流量 188 | DOMAIN-SUFFIX,freeweibo.com,🔰国外流量 189 | DOMAIN-SUFFIX,friday.tw,🔰国外流量 190 | DOMAIN-SUFFIX,ftchinese.com,🔰国外流量 191 | DOMAIN-SUFFIX,ftimg.net,🔰国外流量 192 | DOMAIN-SUFFIX,gate.io,🔰国外流量 193 | DOMAIN-SUFFIX,getlantern.org,🔰国外流量 194 | DOMAIN-SUFFIX,getsync.com,🔰国外流量 195 | DOMAIN-SUFFIX,globalvoices.org,🔰国外流量 196 | DOMAIN-SUFFIX,goo.ne.jp,🔰国外流量 197 | DOMAIN-SUFFIX,goodreads.com,🔰国外流量 198 | DOMAIN-SUFFIX,gov,🔰国外流量 199 | DOMAIN-SUFFIX,gov.tw,🔰国外流量 200 | DOMAIN-SUFFIX,greatfire.org,🔰国外流量 201 | DOMAIN-SUFFIX,gumroad.com,🔰国外流量 202 | DOMAIN-SUFFIX,hbg.com,🔰国外流量 203 | DOMAIN-SUFFIX,heroku.com,🔰国外流量 204 | DOMAIN-SUFFIX,hightail.com,🔰国外流量 205 | DOMAIN-SUFFIX,hk01.com,🔰国外流量 206 | DOMAIN-SUFFIX,hkbf.org,🔰国外流量 207 | DOMAIN-SUFFIX,hkbookcity.com,🔰国外流量 208 | DOMAIN-SUFFIX,hkej.com,🔰国外流量 209 | DOMAIN-SUFFIX,hket.com,🔰国外流量 210 | DOMAIN-SUFFIX,hkgolden.com,🔰国外流量 211 | DOMAIN-SUFFIX,hootsuite.com,🔰国外流量 212 | DOMAIN-SUFFIX,hudson.org,🔰国外流量 213 | DOMAIN-SUFFIX,hyread.com.tw,🔰国外流量 214 | DOMAIN-SUFFIX,ibtimes.com,🔰国外流量 215 | DOMAIN-SUFFIX,i-cable.com,🔰国外流量 216 | DOMAIN-SUFFIX,icij.org,🔰国外流量 217 | DOMAIN-SUFFIX,icoco.com,🔰国外流量 218 | DOMAIN-SUFFIX,imgur.com,🔰国外流量 219 | DOMAIN-SUFFIX,initiummall.com,🔰国外流量 220 | DOMAIN-SUFFIX,insecam.org,🔰国外流量 221 | DOMAIN-SUFFIX,ipfs.io,🔰国外流量 222 | DOMAIN-SUFFIX,issuu.com,🔰国外流量 223 | DOMAIN-SUFFIX,istockphoto.com,🔰国外流量 224 | DOMAIN-SUFFIX,japantimes.co.jp,🔰国外流量 225 | DOMAIN-SUFFIX,jiji.com,🔰国外流量 226 | DOMAIN-SUFFIX,jinx.com,🔰国外流量 227 | DOMAIN-SUFFIX,jkforum.net,🔰国外流量 228 | DOMAIN-SUFFIX,joinmastodon.org,🔰国外流量 229 | DOMAIN-SUFFIX,justmysocks.net,🔰国外流量 230 | DOMAIN-SUFFIX,justpaste.it,🔰国外流量 231 | DOMAIN-SUFFIX,kakao.com,🔰国外流量 232 | DOMAIN-SUFFIX,kakaocorp.com,🔰国外流量 233 | DOMAIN-SUFFIX,kik.com,🔰国外流量 234 | DOMAIN-SUFFIX,kobo.com,🔰国外流量 235 | DOMAIN-SUFFIX,kobobooks.com,🔰国外流量 236 | DOMAIN-SUFFIX,kodingen.com,🔰国外流量 237 | DOMAIN-SUFFIX,lemonde.fr,🔰国外流量 238 | DOMAIN-SUFFIX,lepoint.fr,🔰国外流量 239 | DOMAIN-SUFFIX,lihkg.com,🔰国外流量 240 | DOMAIN-SUFFIX,listennotes.com,🔰国外流量 241 | DOMAIN-SUFFIX,livestream.com,🔰国外流量 242 | DOMAIN-SUFFIX,logmein.com,🔰国外流量 243 | DOMAIN-SUFFIX,mail.ru,🔰国外流量 244 | DOMAIN-SUFFIX,mailchimp.com,🔰国外流量 245 | DOMAIN-SUFFIX,marc.info,🔰国外流量 246 | DOMAIN-SUFFIX,matters.news,🔰国外流量 247 | DOMAIN-SUFFIX,maying.co,🔰国外流量 248 | DOMAIN-SUFFIX,medium.com,🔰国外流量 249 | DOMAIN-SUFFIX,mega.nz,🔰国外流量 250 | DOMAIN-SUFFIX,mil,🔰国外流量 251 | DOMAIN-SUFFIX,mingpao.com,🔰国外流量 252 | DOMAIN-SUFFIX,mobile01.com,🔰国外流量 253 | DOMAIN-SUFFIX,myspace.com,🔰国外流量 254 | DOMAIN-SUFFIX,myspacecdn.com,🔰国外流量 255 | DOMAIN-SUFFIX,nanyang.com,🔰国外流量 256 | DOMAIN-SUFFIX,naver.com,🔰国外流量 257 | DOMAIN-SUFFIX,neowin.net,🔰国外流量 258 | DOMAIN-SUFFIX,newstapa.org,🔰国外流量 259 | DOMAIN-SUFFIX,nexitally.com,🔰国外流量 260 | DOMAIN-SUFFIX,nhk.or.jp,🔰国外流量 261 | DOMAIN-SUFFIX,nicovideo.jp,🔰国外流量 262 | DOMAIN-SUFFIX,nii.ac.jp,🔰国外流量 263 | DOMAIN-SUFFIX,nikkei.com,🔰国外流量 264 | DOMAIN-SUFFIX,nofile.io,🔰国外流量 265 | DOMAIN-SUFFIX,now.com,🔰国外流量 266 | DOMAIN-SUFFIX,nrk.no,🔰国外流量 267 | DOMAIN-SUFFIX,nyt.com,🔰国外流量 268 | DOMAIN-SUFFIX,nytchina.com,🔰国外流量 269 | DOMAIN-SUFFIX,nytcn.me,🔰国外流量 270 | DOMAIN-SUFFIX,nytco.com,🔰国外流量 271 | DOMAIN-SUFFIX,nytimes.com,🔰国外流量 272 | DOMAIN-SUFFIX,nytimg.com,🔰国外流量 273 | DOMAIN-SUFFIX,nytlog.com,🔰国外流量 274 | DOMAIN-SUFFIX,nytstyle.com,🔰国外流量 275 | DOMAIN-SUFFIX,ok.ru,🔰国外流量 276 | DOMAIN-SUFFIX,okex.com,🔰国外流量 277 | DOMAIN-SUFFIX,on.cc,🔰国外流量 278 | DOMAIN-SUFFIX,orientaldaily.com.my,🔰国外流量 279 | DOMAIN-SUFFIX,overcast.fm,🔰国外流量 280 | DOMAIN-SUFFIX,paltalk.com,🔰国外流量 281 | DOMAIN-SUFFIX,pao-pao.net,🔰国外流量 282 | DOMAIN-SUFFIX,parsevideo.com,🔰国外流量 283 | DOMAIN-SUFFIX,pbxes.com,🔰国外流量 284 | DOMAIN-SUFFIX,pcdvd.com.tw,🔰国外流量 285 | DOMAIN-SUFFIX,pchome.com.tw,🔰国外流量 286 | DOMAIN-SUFFIX,pcloud.com,🔰国外流量 287 | DOMAIN-SUFFIX,picacomic.com,🔰国外流量 288 | DOMAIN-SUFFIX,pinimg.com,🔰国外流量 289 | DOMAIN-SUFFIX,pixiv.net,🔰国外流量 290 | DOMAIN-SUFFIX,player.fm,🔰国外流量 291 | DOMAIN-SUFFIX,plurk.com,🔰国外流量 292 | DOMAIN-SUFFIX,po18.tw,🔰国外流量 293 | DOMAIN-SUFFIX,potato.im,🔰国外流量 294 | DOMAIN-SUFFIX,potatso.com,🔰国外流量 295 | DOMAIN-SUFFIX,prism-break.org,🔰国外流量 296 | DOMAIN-SUFFIX,proxifier.com,🔰国外流量 297 | DOMAIN-SUFFIX,pt.im,🔰国外流量 298 | DOMAIN-SUFFIX,pts.org.tw,🔰国外流量 299 | DOMAIN-SUFFIX,pubu.com.tw,🔰国外流量 300 | DOMAIN-SUFFIX,pubu.tw,🔰国外流量 301 | DOMAIN-SUFFIX,pureapk.com,🔰国外流量 302 | DOMAIN-SUFFIX,quora.com,🔰国外流量 303 | DOMAIN-SUFFIX,quoracdn.net,🔰国外流量 304 | DOMAIN-SUFFIX,rakuten.co.jp,🔰国外流量 305 | DOMAIN-SUFFIX,readingtimes.com.tw,🔰国外流量 306 | DOMAIN-SUFFIX,readmoo.com,🔰国外流量 307 | DOMAIN-SUFFIX,redbubble.com,🔰国外流量 308 | DOMAIN-SUFFIX,reddit.com,🔰国外流量 309 | DOMAIN-SUFFIX,redditmedia.com,🔰国外流量 310 | DOMAIN-SUFFIX,resilio.com,🔰国外流量 311 | DOMAIN-SUFFIX,reuters.com,🔰国外流量 312 | DOMAIN-SUFFIX,reutersmedia.net,🔰国外流量 313 | DOMAIN-SUFFIX,rfi.fr,🔰国外流量 314 | DOMAIN-SUFFIX,rixcloud.com,🔰国外流量 315 | DOMAIN-SUFFIX,roadshow.hk,🔰国外流量 316 | DOMAIN-SUFFIX,scmp.com,🔰国外流量 317 | DOMAIN-SUFFIX,scribd.com,🔰国外流量 318 | DOMAIN-SUFFIX,seatguru.com,🔰国外流量 319 | DOMAIN-SUFFIX,shadowsocks.org,🔰国外流量 320 | DOMAIN-SUFFIX,shopee.tw,🔰国外流量 321 | DOMAIN-SUFFIX,slideshare.net,🔰国外流量 322 | DOMAIN-SUFFIX,softfamous.com,🔰国外流量 323 | DOMAIN-SUFFIX,soundcloud.com,🔰国外流量 324 | DOMAIN-SUFFIX,ssrcloud.org,🔰国外流量 325 | DOMAIN-SUFFIX,startpage.com,🔰国外流量 326 | DOMAIN-SUFFIX,steamcommunity.com,🔰国外流量 327 | DOMAIN-SUFFIX,steemit.com,🔰国外流量 328 | DOMAIN-SUFFIX,steemitwallet.com,🔰国外流量 329 | DOMAIN-SUFFIX,t66y.com,🔰国外流量 330 | DOMAIN-SUFFIX,tapatalk.com,🔰国外流量 331 | DOMAIN-SUFFIX,teco-hk.org,🔰国外流量 332 | DOMAIN-SUFFIX,teco-mo.org,🔰国外流量 333 | DOMAIN-SUFFIX,teddysun.com,🔰国外流量 334 | DOMAIN-SUFFIX,textnow.me,🔰国外流量 335 | DOMAIN-SUFFIX,theguardian.com,🔰国外流量 336 | DOMAIN-SUFFIX,theinitium.com,🔰国外流量 337 | DOMAIN-SUFFIX,thetvdb.com,🔰国外流量 338 | DOMAIN-SUFFIX,tineye.com,🔰国外流量 339 | DOMAIN-SUFFIX,torproject.org,🔰国外流量 340 | DOMAIN-SUFFIX,tumblr.com,🔰国外流量 341 | DOMAIN-SUFFIX,turbobit.net,🔰国外流量 342 | DOMAIN-SUFFIX,tutanota.com,🔰国外流量 343 | DOMAIN-SUFFIX,tvboxnow.com,🔰国外流量 344 | DOMAIN-SUFFIX,udn.com,🔰国外流量 345 | DOMAIN-SUFFIX,unseen.is,🔰国外流量 346 | DOMAIN-SUFFIX,upmedia.mg,🔰国外流量 347 | DOMAIN-SUFFIX,uptodown.com,🔰国外流量 348 | DOMAIN-SUFFIX,urbandictionary.com,🔰国外流量 349 | DOMAIN-SUFFIX,ustream.tv,🔰国外流量 350 | DOMAIN-SUFFIX,uwants.com,🔰国外流量 351 | DOMAIN-SUFFIX,v2ray.com,🔰国外流量 352 | DOMAIN-SUFFIX,viber.com,🔰国外流量 353 | DOMAIN-SUFFIX,videopress.com,🔰国外流量 354 | DOMAIN-SUFFIX,vimeo.com,🔰国外流量 355 | DOMAIN-SUFFIX,voachinese.com,🔰国外流量 356 | DOMAIN-SUFFIX,voanews.com,🔰国外流量 357 | DOMAIN-SUFFIX,voxer.com,🔰国外流量 358 | DOMAIN-SUFFIX,vzw.com,🔰国外流量 359 | DOMAIN-SUFFIX,w3schools.com,🔰国外流量 360 | DOMAIN-SUFFIX,washingtonpost.com,🔰国外流量 361 | DOMAIN-SUFFIX,wattpad.com,🔰国外流量 362 | DOMAIN-SUFFIX,whoer.net,🔰国外流量 363 | DOMAIN-SUFFIX,wikimapia.org,🔰国外流量 364 | DOMAIN-SUFFIX,wikipedia.org,🔰国外流量 365 | DOMAIN-SUFFIX,wikiquote.org,🔰国外流量 366 | DOMAIN-SUFFIX,wikiwand.com,🔰国外流量 367 | DOMAIN-SUFFIX,winudf.com,🔰国外流量 368 | DOMAIN-SUFFIX,wire.com,🔰国外流量 369 | DOMAIN-SUFFIX,wordpress.com,🔰国外流量 370 | DOMAIN-SUFFIX,workflow.is,🔰国外流量 371 | DOMAIN-SUFFIX,worldcat.org,🔰国外流量 372 | DOMAIN-SUFFIX,wsj.com,🔰国外流量 373 | DOMAIN-SUFFIX,wsj.net,🔰国外流量 374 | DOMAIN-SUFFIX,xhamster.com,🔰国外流量 375 | DOMAIN-SUFFIX,xn--90wwvt03e.com,🔰国外流量 376 | DOMAIN-SUFFIX,xn--i2ru8q2qg.com,🔰国外流量 377 | DOMAIN-SUFFIX,xnxx.com,🔰国外流量 378 | DOMAIN-SUFFIX,xvideos.com,🔰国外流量 379 | DOMAIN-SUFFIX,yahoo.com,🔰国外流量 380 | DOMAIN-SUFFIX,yandex.ru,🔰国外流量 381 | DOMAIN-SUFFIX,ycombinator.com,🔰国外流量 382 | DOMAIN-SUFFIX,yesasia.com,🔰国外流量 383 | DOMAIN-SUFFIX,yes-news.com,🔰国外流量 384 | DOMAIN-SUFFIX,yomiuri.co.jp,🔰国外流量 385 | DOMAIN-SUFFIX,you-get.org,🔰国外流量 386 | DOMAIN-SUFFIX,zaobao.com,🔰国外流量 387 | DOMAIN-SUFFIX,zb.com,🔰国外流量 388 | DOMAIN-SUFFIX,zello.com,🔰国外流量 389 | DOMAIN-SUFFIX,zeronet.io,🔰国外流量 390 | DOMAIN-SUFFIX,zoom.us,🔰国外流量 391 | DOMAIN-KEYWORD,github,🔰国外流量 392 | DOMAIN-KEYWORD,jav,🔰国外流量 393 | DOMAIN-KEYWORD,pinterest,🔰国外流量 394 | DOMAIN-KEYWORD,porn,🔰国外流量 395 | DOMAIN-KEYWORD,wikileaks,🔰国外流量 396 | DOMAIN-SUFFIX,apartmentratings.com,🔰国外流量 397 | DOMAIN-SUFFIX,apartments.com,🔰国外流量 398 | DOMAIN-SUFFIX,bankmobilevibe.com,🔰国外流量 399 | DOMAIN-SUFFIX,bing.com,🔰国外流量 400 | DOMAIN-SUFFIX,booktopia.com.au,🔰国外流量 401 | DOMAIN-SUFFIX,cccat.io,🔰国外流量 402 | DOMAIN-SUFFIX,centauro.com.br,🔰国外流量 403 | DOMAIN-SUFFIX,clearsurance.com,🔰国外流量 404 | DOMAIN-SUFFIX,costco.com,🔰国外流量 405 | DOMAIN-SUFFIX,crackle.com,🔰国外流量 406 | DOMAIN-SUFFIX,depositphotos.cn,🔰国外流量 407 | DOMAIN-SUFFIX,dish.com,🔰国外流量 408 | DOMAIN-SUFFIX,dmm.co.jp,🔰国外流量 409 | DOMAIN-SUFFIX,dmm.com,🔰国外流量 410 | DOMAIN-SUFFIX,dnvod.tv,🔰国外流量 411 | DOMAIN-SUFFIX,esurance.com,🔰国外流量 412 | DOMAIN-SUFFIX,extmatrix.com,🔰国外流量 413 | DOMAIN-SUFFIX,fastpic.ru,🔰国外流量 414 | DOMAIN-SUFFIX,flipboard.com,🔰国外流量 415 | DOMAIN-SUFFIX,fnac.be,🔰国外流量 416 | DOMAIN-SUFFIX,fnac.com,🔰国外流量 417 | DOMAIN-SUFFIX,funkyimg.com,🔰国外流量 418 | DOMAIN-SUFFIX,fxnetworks.com,🔰国外流量 419 | DOMAIN-SUFFIX,gettyimages.com,🔰国外流量 420 | DOMAIN-SUFFIX,go.com,🔰国外流量 421 | DOMAIN-SUFFIX,here.com,🔰国外流量 422 | DOMAIN-SUFFIX,jcpenney.com,🔰国外流量 423 | DOMAIN-SUFFIX,jiehua.tv,🔰国外流量 424 | DOMAIN-SUFFIX,mailfence.com,🔰国外流量 425 | DOMAIN-SUFFIX,nationwide.com,🔰国外流量 426 | DOMAIN-SUFFIX,nbc.com,🔰国外流量 427 | DOMAIN-SUFFIX,nexon.com,🔰国外流量 428 | DOMAIN-SUFFIX,nordstrom.com,🔰国外流量 429 | DOMAIN-SUFFIX,nordstromimage.com,🔰国外流量 430 | DOMAIN-SUFFIX,nordstromrack.com,🔰国外流量 431 | DOMAIN-SUFFIX,superpages.com,🔰国外流量 432 | DOMAIN-SUFFIX,target.com,🔰国外流量 433 | DOMAIN-SUFFIX,thinkgeek.com,🔰国外流量 434 | DOMAIN-SUFFIX,tracfone.com,🔰国外流量 435 | DOMAIN-SUFFIX,unity3d.com,🔰国外流量 436 | DOMAIN-SUFFIX,uploader.jp,🔰国外流量 437 | DOMAIN-SUFFIX,vevo.com,🔰国外流量 438 | DOMAIN-SUFFIX,viu.tv,🔰国外流量 439 | DOMAIN-SUFFIX,vk.com,🔰国外流量 440 | DOMAIN-SUFFIX,vsco.co,🔰国外流量 441 | DOMAIN-SUFFIX,xfinity.com,🔰国外流量 442 | DOMAIN-SUFFIX,zattoo.com,🔰国外流量 443 | USER-AGENT,Roam*,🔰国外流量 444 | DOMAIN,testflight.apple.com,🔰国外流量 445 | DOMAIN-SUFFIX,appsto.re,🔰国外流量 446 | DOMAIN,books.itunes.apple.com,🔰国外流量 447 | DOMAIN,hls.itunes.apple.com,🔰国外流量 448 | DOMAIN,apps.apple.com,🔰国外流量 449 | DOMAIN,itunes.apple.com,🔰国外流量 450 | DOMAIN,api-glb-sea.smoot.apple.com,🔰国外流量 451 | DOMAIN,lookup-api.apple.com,🔰国外流量 452 | PROCESS-NAME,LookupViewService,🔰国外流量 453 | DOMAIN-SUFFIX,abc.xyz,🔰国外流量 454 | DOMAIN-SUFFIX,android.com,🔰国外流量 455 | DOMAIN-SUFFIX,androidify.com,🔰国外流量 456 | DOMAIN-SUFFIX,dialogflow.com,🔰国外流量 457 | DOMAIN-SUFFIX,autodraw.com,🔰国外流量 458 | DOMAIN-SUFFIX,capitalg.com,🔰国外流量 459 | DOMAIN-SUFFIX,certificate-transparency.org,🔰国外流量 460 | DOMAIN-SUFFIX,chrome.com,🔰国外流量 461 | DOMAIN-SUFFIX,chromeexperiments.com,🔰国外流量 462 | DOMAIN-SUFFIX,chromestatus.com,🔰国外流量 463 | DOMAIN-SUFFIX,chromium.org,🔰国外流量 464 | DOMAIN-SUFFIX,creativelab5.com,🔰国外流量 465 | DOMAIN-SUFFIX,debug.com,🔰国外流量 466 | DOMAIN-SUFFIX,deepmind.com,🔰国外流量 467 | DOMAIN-SUFFIX,firebaseio.com,🔰国外流量 468 | DOMAIN-SUFFIX,getmdl.io,🔰国外流量 469 | DOMAIN-SUFFIX,ggpht.com,🔰国外流量 470 | DOMAIN-SUFFIX,gmail.com,🔰国外流量 471 | DOMAIN-SUFFIX,gmodules.com,🔰国外流量 472 | DOMAIN-SUFFIX,godoc.org,🔰国外流量 473 | DOMAIN-SUFFIX,golang.org,🔰国外流量 474 | DOMAIN-SUFFIX,gstatic.com,🔰国外流量 475 | DOMAIN-SUFFIX,gv.com,🔰国外流量 476 | DOMAIN-SUFFIX,gwtproject.org,🔰国外流量 477 | DOMAIN-SUFFIX,itasoftware.com,🔰国外流量 478 | DOMAIN-SUFFIX,madewithcode.com,🔰国外流量 479 | DOMAIN-SUFFIX,material.io,🔰国外流量 480 | DOMAIN-SUFFIX,polymer-project.org,🔰国外流量 481 | DOMAIN-SUFFIX,admin.recaptcha.net,🔰国外流量 482 | DOMAIN-SUFFIX,recaptcha.net,🔰国外流量 483 | DOMAIN-SUFFIX,shattered.io,🔰国外流量 484 | DOMAIN-SUFFIX,synergyse.com,🔰国外流量 485 | DOMAIN-SUFFIX,tensorflow.org,🔰国外流量 486 | DOMAIN-SUFFIX,tfhub.dev,🔰国外流量 487 | DOMAIN-SUFFIX,tiltbrush.com,🔰国外流量 488 | DOMAIN-SUFFIX,waveprotocol.org,🔰国外流量 489 | DOMAIN-SUFFIX,waymo.com,🔰国外流量 490 | DOMAIN-SUFFIX,webmproject.org,🔰国外流量 491 | DOMAIN-SUFFIX,webrtc.org,🔰国外流量 492 | DOMAIN-SUFFIX,whatbrowser.org,🔰国外流量 493 | DOMAIN-SUFFIX,widevine.com,🔰国外流量 494 | DOMAIN-SUFFIX,x.company,🔰国外流量 495 | DOMAIN-SUFFIX,youtu.be,🔰国外流量 496 | DOMAIN-SUFFIX,yt.be,🔰国外流量 497 | DOMAIN-SUFFIX,ytimg.com,🔰国外流量 498 | DOMAIN-SUFFIX,1drv.com,🔰国外流量 499 | DOMAIN-SUFFIX,1drv.ms,🔰国外流量 500 | DOMAIN-SUFFIX,blob.core.windows.net,🔰国外流量 501 | DOMAIN-SUFFIX,livefilestore.com,🔰国外流量 502 | DOMAIN-SUFFIX,onedrive.com,🔰国外流量 503 | DOMAIN-SUFFIX,storage.live.com,🔰国外流量 504 | DOMAIN-SUFFIX,storage.msn.com,🔰国外流量 505 | DOMAIN,oneclient.sfx.ms,🔰国外流量 506 | DOMAIN-SUFFIX,0rz.tw,🔰国外流量 507 | DOMAIN-SUFFIX,4bluestones.biz,🔰国外流量 508 | DOMAIN-SUFFIX,9bis.net,🔰国外流量 509 | DOMAIN-SUFFIX,allconnected.co,🔰国外流量 510 | DOMAIN-SUFFIX,aol.com,🔰国外流量 511 | DOMAIN-SUFFIX,bcc.com.tw,🔰国外流量 512 | DOMAIN-SUFFIX,bit.ly,🔰国外流量 513 | DOMAIN-SUFFIX,bitshare.com,🔰国外流量 514 | DOMAIN-SUFFIX,blog.jp,🔰国外流量 515 | DOMAIN-SUFFIX,blogimg.jp,🔰国外流量 516 | DOMAIN-SUFFIX,blogtd.org,🔰国外流量 517 | DOMAIN-SUFFIX,broadcast.co.nz,🔰国外流量 518 | DOMAIN-SUFFIX,camfrog.com,🔰国外流量 519 | DOMAIN-SUFFIX,cfos.de,🔰国外流量 520 | DOMAIN-SUFFIX,citypopulation.de,🔰国外流量 521 | DOMAIN-SUFFIX,cloudfront.net,🔰国外流量 522 | DOMAIN-SUFFIX,ctitv.com.tw,🔰国外流量 523 | DOMAIN-SUFFIX,cuhk.edu.hk,🔰国外流量 524 | DOMAIN-SUFFIX,cusu.hk,🔰国外流量 525 | DOMAIN-SUFFIX,discord.gg,🔰国外流量 526 | DOMAIN-SUFFIX,discuss.com.hk,🔰国外流量 527 | DOMAIN-SUFFIX,dropboxapi.com,🔰国外流量 528 | DOMAIN-SUFFIX,duolingo.cn,🔰国外流量 529 | DOMAIN-SUFFIX,edditstatic.com,🔰国外流量 530 | DOMAIN-SUFFIX,flickriver.com,🔰国外流量 531 | DOMAIN-SUFFIX,focustaiwan.tw,🔰国外流量 532 | DOMAIN-SUFFIX,free.fr,🔰国外流量 533 | DOMAIN-SUFFIX,gigacircle.com,🔰国外流量 534 | DOMAIN-SUFFIX,hk-pub.com,🔰国外流量 535 | DOMAIN-SUFFIX,hosting.co.uk,🔰国外流量 536 | DOMAIN-SUFFIX,hwcdn.net,🔰国外流量 537 | DOMAIN-SUFFIX,ifixit.com,🔰国外流量 538 | DOMAIN-SUFFIX,iphone4hongkong.com,🔰国外流量 539 | DOMAIN-SUFFIX,iphonetaiwan.org,🔰国外流量 540 | DOMAIN-SUFFIX,iptvbin.com,🔰国外流量 541 | DOMAIN-SUFFIX,linksalpha.com,🔰国外流量 542 | DOMAIN-SUFFIX,manyvids.com,🔰国外流量 543 | DOMAIN-SUFFIX,myactimes.com,🔰国外流量 544 | DOMAIN-SUFFIX,newsblur.com,🔰国外流量 545 | DOMAIN-SUFFIX,now.im,🔰国外流量 546 | DOMAIN-SUFFIX,nowe.com,🔰国外流量 547 | DOMAIN-SUFFIX,redditlist.com,🔰国外流量 548 | DOMAIN-SUFFIX,s3.amazonaws.com,🔰国外流量 549 | DOMAIN-SUFFIX,signal.org,🔰国外流量 550 | DOMAIN-SUFFIX,smartmailcloud.com,🔰国外流量 551 | DOMAIN-SUFFIX,sparknotes.com,🔰国外流量 552 | DOMAIN-SUFFIX,streetvoice.com,🔰国外流量 553 | DOMAIN-SUFFIX,supertop.co,🔰国外流量 554 | DOMAIN-SUFFIX,tv.com,🔰国外流量 555 | DOMAIN-SUFFIX,typepad.com,🔰国外流量 556 | DOMAIN-SUFFIX,udnbkk.com,🔰国外流量 557 | DOMAIN-SUFFIX,urbanairship.com,🔰国外流量 558 | DOMAIN-SUFFIX,whispersystems.org,🔰国外流量 559 | DOMAIN-SUFFIX,wikia.com,🔰国外流量 560 | DOMAIN-SUFFIX,wn.com,🔰国外流量 561 | DOMAIN-SUFFIX,wolframalpha.com,🔰国外流量 562 | DOMAIN-SUFFIX,x-art.com,🔰国外流量 563 | DOMAIN-SUFFIX,yimg.com,🔰国外流量 564 | DOMAIN,api.steampowered.com,🔰国外流量 565 | DOMAIN,store.steampowered.com,🔰国外流量 566 | 567 | DOMAIN-SUFFIX,t.me,✈️Telegram 568 | DOMAIN-SUFFIX,tdesktop.com,✈️Telegram 569 | DOMAIN-SUFFIX,telegra.ph,✈️Telegram 570 | DOMAIN-SUFFIX,telegram.me,✈️Telegram 571 | DOMAIN-SUFFIX,telegram.org,✈️Telegram 572 | IP-CIDR,91.108.4.0/22,✈️Telegram,no-resolve 573 | IP-CIDR,91.108.8.0/22,✈️Telegram,no-resolve 574 | IP-CIDR,91.108.12.0/22,✈️Telegram,no-resolve 575 | IP-CIDR,91.108.16.0/22,✈️Telegram,no-resolve 576 | IP-CIDR,91.108.56.0/22,✈️Telegram,no-resolve 577 | IP-CIDR,149.154.160.0/20,✈️Telegram,no-resolve 578 | IP-CIDR6,2001:b28:f23d::/48,✈️Telegram,no-resolve 579 | IP-CIDR6,2001:b28:f23f::/48,✈️Telegram,no-resolve 580 | IP-CIDR6,2001:67c:4e8::/48,✈️Telegram,no-resolve 581 | 582 | USER-AGENT,com.google.ios.youtube*,🎬Youtube 583 | USER-AGENT,YouTube*,🎬Youtube 584 | DOMAIN-SUFFIX,googlevideo.com,🎬Youtube 585 | DOMAIN-SUFFIX,youtube.com,🎬Youtube 586 | DOMAIN,youtubei.googleapis.com,🎬Youtube 587 | 588 | USER-AGENT,Argo*,🎬Netflix 589 | DOMAIN-SUFFIX,netflix.com,🎬Netflix 590 | DOMAIN-SUFFIX,netflix.net,🎬Netflix 591 | DOMAIN-SUFFIX,nflxext.com,🎬Netflix 592 | DOMAIN-SUFFIX,nflximg.com,🎬Netflix 593 | DOMAIN-SUFFIX,nflximg.net,🎬Netflix 594 | DOMAIN-SUFFIX,nflxso.net,🎬Netflix 595 | DOMAIN-SUFFIX,nflxvideo.net,🎬Netflix 596 | DOMAIN-SUFFIX,netflixdnstest0.com,🎬Netflix 597 | DOMAIN-SUFFIX,netflixdnstest1.com,🎬Netflix 598 | DOMAIN-SUFFIX,netflixdnstest2.com,🎬Netflix 599 | DOMAIN-SUFFIX,netflixdnstest3.com,🎬Netflix 600 | DOMAIN-SUFFIX,netflixdnstest4.com,🎬Netflix 601 | DOMAIN-SUFFIX,netflixdnstest5.com,🎬Netflix 602 | DOMAIN-SUFFIX,netflixdnstest6.com,🎬Netflix 603 | DOMAIN-SUFFIX,netflixdnstest7.com,🎬Netflix 604 | DOMAIN-SUFFIX,netflixdnstest8.com,🎬Netflix 605 | DOMAIN-SUFFIX,netflixdnstest9.com,🎬Netflix 606 | IP-CIDR,23.246.0.0/18,🎬Netflix,no-resolve 607 | IP-CIDR,37.77.184.0/21,🎬Netflix,no-resolve 608 | IP-CIDR,45.57.0.0/17,🎬Netflix,no-resolve 609 | IP-CIDR,64.120.128.0/17,🎬Netflix,no-resolve 610 | IP-CIDR,66.197.128.0/17,🎬Netflix,no-resolve 611 | IP-CIDR,108.175.32.0/20,🎬Netflix,no-resolve 612 | IP-CIDR,192.173.64.0/18,🎬Netflix,no-resolve 613 | IP-CIDR,198.38.96.0/19,🎬Netflix,no-resolve 614 | IP-CIDR,198.45.48.0/20,🎬Netflix,no-resolve 615 | 616 | USER-AGENT,Deezer*,🎬国外媒体 617 | DOMAIN-SUFFIX,deezer.com,🎬国外媒体 618 | DOMAIN-SUFFIX,dzcdn.net,🎬国外媒体 619 | DOMAIN-SUFFIX,kkbox.com,🎬国外媒体 620 | DOMAIN-SUFFIX,kkbox.com.tw,🎬国外媒体 621 | DOMAIN-SUFFIX,kfs.io,🎬国外媒体 622 | USER-AGENT,WeMusic*,🎬国外媒体 623 | USER-AGENT,JOOX*,🎬国外媒体 624 | DOMAIN-SUFFIX,joox.com,🎬国外媒体 625 | USER-AGENT,Pandora*,🎬国外媒体 626 | DOMAIN-SUFFIX,pandora.com,🎬国外媒体 627 | USER-AGENT,SoundCloud*,🎬国外媒体 628 | DOMAIN-SUFFIX,p-cdn.us,🎬国外媒体 629 | DOMAIN-SUFFIX,sndcdn.com,🎬国外媒体 630 | DOMAIN-SUFFIX,soundcloud.com,🎬国外媒体 631 | USER-AGENT,Spotify*,🎬国外媒体 632 | DOMAIN-SUFFIX,pscdn.co,🎬国外媒体 633 | DOMAIN-SUFFIX,scdn.co,🎬国外媒体 634 | DOMAIN-SUFFIX,spotify.com,🎬国外媒体 635 | DOMAIN-SUFFIX,spoti.fi,🎬国外媒体 636 | DOMAIN-KEYWORD,spotify.com,🎬国外媒体 637 | DOMAIN-KEYWORD,-spotify-com,🎬国外媒体 638 | USER-AGENT,TIDAL*,🎬国外媒体 639 | DOMAIN-SUFFIX,tidal.com,🎬国外媒体 640 | USER-AGENT,com.google.ios.youtubemusic*,🎬国外媒体 641 | USER-AGENT,YouTubeMusic*,🎬国外媒体 642 | USER-AGENT,All4*,🎬国外媒体 643 | DOMAIN-SUFFIX,c4assets.com,🎬国外媒体 644 | DOMAIN-SUFFIX,channel4.com,🎬国外媒体 645 | USER-AGENT,AbemaTV*,🎬国外媒体 646 | DOMAIN-SUFFIX,abema.io,🎬国外媒体 647 | DOMAIN-SUFFIX,ameba.jp,🎬国外媒体 648 | DOMAIN-SUFFIX,abema.tv,🎬国外媒体 649 | DOMAIN-SUFFIX,hayabusa.io,🎬国外媒体 650 | DOMAIN,abematv.akamaized.net,🎬国外媒体 651 | DOMAIN,ds-linear-abematv.akamaized.net,🎬国外媒体 652 | DOMAIN,ds-vod-abematv.akamaized.net,🎬国外媒体 653 | DOMAIN,linear-abematv.akamaized.net,🎬国外媒体 654 | USER-AGENT,InstantVideo.US*,🎬国外媒体 655 | USER-AGENT,Prime%20Video*,🎬国外媒体 656 | DOMAIN-SUFFIX,aiv-cdn.net,🎬国外媒体 657 | DOMAIN-SUFFIX,aiv-delivery.net,🎬国外媒体 658 | DOMAIN-SUFFIX,amazonvideo.com,🎬国外媒体 659 | DOMAIN-SUFFIX,primevideo.com,🎬国外媒体 660 | DOMAIN,avodmp4s3ww-a.akamaihd.net,🎬国外媒体 661 | DOMAIN,d25xi40x97liuc.cloudfront.net,🎬国外媒体 662 | DOMAIN,dmqdd6hw24ucf.cloudfront.net,🎬国外媒体 663 | DOMAIN,d22qjgkvxw22r6.cloudfront.net,🎬国外媒体 664 | DOMAIN,d1v5ir2lpwr8os.cloudfront.net,🎬国外媒体 665 | DOMAIN-KEYWORD,avoddashs,🎬国外媒体 666 | USER-AGENT,Anime*,🎬国外媒体 667 | DOMAIN-SUFFIX,bahamut.com.tw,🎬国外媒体 668 | DOMAIN-SUFFIX,gamer.com.tw,🎬国外媒体 669 | DOMAIN,gamer-cds.cdn.hinet.net,🎬国外媒体 670 | DOMAIN,gamer2-cds.cdn.hinet.net,🎬国外媒体 671 | USER-AGENT,BBCiPlayer*,🎬国外媒体 672 | DOMAIN-SUFFIX,bbc.co.uk,🎬国外媒体 673 | DOMAIN-SUFFIX,bbci.co.uk,🎬国外媒体 674 | DOMAIN-KEYWORD,bbcfmt,🎬国外媒体 675 | DOMAIN-KEYWORD,uk-live,🎬国外媒体 676 | USER-AGENT,DAZN*,🎬国外媒体 677 | DOMAIN-SUFFIX,dazn.com,🎬国外媒体 678 | DOMAIN-SUFFIX,dazn-api.com,🎬国外媒体 679 | DOMAIN,d151l6v8er5bdm.cloudfront.net,🎬国外媒体 680 | DOMAIN-KEYWORD,voddazn,🎬国外媒体 681 | USER-AGENT,Disney+*,🎬国外媒体 682 | DOMAIN-SUFFIX,bamgrid.com,🎬国外媒体 683 | DOMAIN-SUFFIX,disney-plus.net,🎬国外媒体 684 | DOMAIN-SUFFIX,disneyplus.com,🎬国外媒体 685 | DOMAIN-SUFFIX,dssott.com,🎬国外媒体 686 | DOMAIN,cdn.registerdisney.go.com,🎬国外媒体 687 | USER-AGENT,encoreTVB*,🎬国外媒体 688 | DOMAIN-SUFFIX,encoretvb.com,🎬国外媒体 689 | DOMAIN,edge.api.brightcove.com,🎬国外媒体 690 | DOMAIN,bcbolt446c5271-a.akamaihd.net,🎬国外媒体 691 | USER-AGENT,FOX%20NOW*,🎬国外媒体 692 | DOMAIN-SUFFIX,fox.com,🎬国外媒体 693 | DOMAIN-SUFFIX,foxdcg.com,🎬国外媒体 694 | DOMAIN-SUFFIX,theplatform.com,🎬国外媒体 695 | DOMAIN-SUFFIX,uplynk.com,🎬国外媒体 696 | USER-AGENT,HBO%20NOW*,🎬国外媒体 697 | DOMAIN-SUFFIX,hbo.com,🎬国外媒体 698 | DOMAIN-SUFFIX,hbogo.com,🎬国外媒体 699 | DOMAIN-SUFFIX,hbonow.com,🎬国外媒体 700 | USER-AGENT,HBO%20GO%20PROD%20HKG*,🎬国外媒体 701 | DOMAIN-SUFFIX,hbogoasia.com,🎬国外媒体 702 | DOMAIN-SUFFIX,hbogoasia.hk,🎬国外媒体 703 | DOMAIN,bcbolthboa-a.akamaihd.net,🎬国外媒体 704 | DOMAIN,players.brightcove.net,🎬国外媒体 705 | DOMAIN,s3-ap-southeast-1.amazonaws.com,🎬国外媒体 706 | DOMAIN,dai3fd1oh325y.cloudfront.net,🎬国外媒体 707 | DOMAIN,44wilhpljf.execute-api.ap-southeast-1.amazonaws.com,🎬国外媒体 708 | DOMAIN,hboasia1-i.akamaihd.net,🎬国外媒体 709 | DOMAIN,hboasia2-i.akamaihd.net,🎬国外媒体 710 | DOMAIN,hboasia3-i.akamaihd.net,🎬国外媒体 711 | DOMAIN,hboasia4-i.akamaihd.net,🎬国外媒体 712 | DOMAIN,hboasia5-i.akamaihd.net,🎬国外媒体 713 | DOMAIN,cf-images.ap-southeast-1.prod.boltdns.net,🎬国外媒体 714 | USER-AGENT,HWTVMobile*,🎬国外媒体 715 | DOMAIN-SUFFIX,5itv.tv,🎬国外媒体 716 | DOMAIN-SUFFIX,ocnttv.com,🎬国外媒体 717 | DOMAIN-SUFFIX,hulu.com,🎬国外媒体 718 | DOMAIN-SUFFIX,huluim.com,🎬国外媒体 719 | DOMAIN-SUFFIX,hulustream.com,🎬国外媒体 720 | DOMAIN-SUFFIX,happyon.jp,🎬国外媒体 721 | DOMAIN-SUFFIX,hulu.jp,🎬国外媒体 722 | USER-AGENT,ITV_Player*,🎬国外媒体 723 | DOMAIN-SUFFIX,itv.com,🎬国外媒体 724 | DOMAIN-SUFFIX,itvstatic.com,🎬国外媒体 725 | DOMAIN,itvpnpmobile-a.akamaihd.net,🎬国外媒体 726 | USER-AGENT,KKTV*,🎬国外媒体 727 | USER-AGENT,com.kktv.ios.kktv*,🎬国外媒体 728 | DOMAIN-SUFFIX,kktv.com.tw,🎬国外媒体 729 | DOMAIN-SUFFIX,kktv.me,🎬国外媒体 730 | DOMAIN,kktv-theater.kk.stream,🎬国外媒体 731 | USER-AGENT,LINE%20TV*,🎬国外媒体 732 | DOMAIN-SUFFIX,linetv.tw,🎬国外媒体 733 | DOMAIN,d3c7rimkq79yfu.cloudfront.net,🎬国外媒体 734 | DOMAIN-SUFFIX,litv.tv,🎬国外媒体 735 | DOMAIN,litvfreemobile-hichannel.cdn.hinet.net,🎬国外媒体 736 | USER-AGENT,My5*,🎬国外媒体 737 | DOMAIN-SUFFIX,channel5.com,🎬国外媒体 738 | DOMAIN-SUFFIX,my5.tv,🎬国外媒体 739 | DOMAIN,d349g9zuie06uo.cloudfront.net,🎬国外媒体 740 | USER-AGENT,mytv*,🎬国外媒体 741 | DOMAIN-SUFFIX,mytvsuper.com,🎬国外媒体 742 | DOMAIN-SUFFIX,tvb.com,🎬国外媒体 743 | USER-AGENT,Argo*,🎬国外媒体 744 | DOMAIN-SUFFIX,netflix.com,🎬国外媒体 745 | DOMAIN-SUFFIX,netflix.net,🎬国外媒体 746 | DOMAIN-SUFFIX,nflxext.com,🎬国外媒体 747 | DOMAIN-SUFFIX,nflximg.com,🎬国外媒体 748 | DOMAIN-SUFFIX,nflximg.net,🎬国外媒体 749 | DOMAIN-SUFFIX,nflxso.net,🎬国外媒体 750 | DOMAIN-SUFFIX,nflxvideo.net,🎬国外媒体 751 | DOMAIN-SUFFIX,netflixdnstest0.com,🎬国外媒体 752 | DOMAIN-SUFFIX,netflixdnstest1.com,🎬国外媒体 753 | DOMAIN-SUFFIX,netflixdnstest2.com,🎬国外媒体 754 | DOMAIN-SUFFIX,netflixdnstest3.com,🎬国外媒体 755 | DOMAIN-SUFFIX,netflixdnstest4.com,🎬国外媒体 756 | DOMAIN-SUFFIX,netflixdnstest5.com,🎬国外媒体 757 | DOMAIN-SUFFIX,netflixdnstest6.com,🎬国外媒体 758 | DOMAIN-SUFFIX,netflixdnstest7.com,🎬国外媒体 759 | DOMAIN-SUFFIX,netflixdnstest8.com,🎬国外媒体 760 | DOMAIN-SUFFIX,netflixdnstest9.com,🎬国外媒体 761 | IP-CIDR,23.246.0.0/18,🎬国外媒体,no-resolve 762 | IP-CIDR,37.77.184.0/21,🎬国外媒体,no-resolve 763 | IP-CIDR,45.57.0.0/17,🎬国外媒体,no-resolve 764 | IP-CIDR,64.120.128.0/17,🎬国外媒体,no-resolve 765 | IP-CIDR,66.197.128.0/17,🎬国外媒体,no-resolve 766 | IP-CIDR,108.175.32.0/20,🎬国外媒体,no-resolve 767 | IP-CIDR,192.173.64.0/18,🎬国外媒体,no-resolve 768 | IP-CIDR,198.38.96.0/19,🎬国外媒体,no-resolve 769 | IP-CIDR,198.45.48.0/20,🎬国外媒体,no-resolve 770 | USER-AGENT,Niconico*,🎬国外媒体 771 | DOMAIN-SUFFIX,dmc.nico,🎬国外媒体 772 | DOMAIN-SUFFIX,nicovideo.jp,🎬国外媒体 773 | DOMAIN-SUFFIX,nimg.jp,🎬国外媒体 774 | DOMAIN-SUFFIX,socdm.com,🎬国外媒体 775 | USER-AGENT,PBS*,🎬国外媒体 776 | DOMAIN-SUFFIX,pbs.org,🎬国外媒体 777 | DOMAIN-SUFFIX,phncdn.com,🎬国外媒体 778 | DOMAIN-SUFFIX,pornhub.com,🎬国外媒体 779 | DOMAIN-SUFFIX,pornhubpremium.com,🎬国外媒体 780 | USER-AGENT,TaiwanGood*,🎬国外媒体 781 | DOMAIN-SUFFIX,skyking.com.tw,🎬国外媒体 782 | DOMAIN,hamifans.emome.net,🎬国外媒体 783 | DOMAIN-SUFFIX,twitch.tv,🎬国外媒体 784 | DOMAIN-SUFFIX,twitchcdn.net,🎬国外媒体 785 | DOMAIN-SUFFIX,ttvnw.net,🎬国外媒体 786 | DOMAIN-SUFFIX,jtvnw.net,🎬国外媒体 787 | USER-AGENT,Viu*,🎬国外媒体 788 | USER-AGENT,ViuTV*,🎬国外媒体 789 | DOMAIN-SUFFIX,viu.com,🎬国外媒体 790 | DOMAIN-SUFFIX,viu.tv,🎬国外媒体 791 | DOMAIN,api.viu.now.com,🎬国外媒体 792 | DOMAIN,d1k2us671qcoau.cloudfront.net,🎬国外媒体 793 | DOMAIN,d2anahhhmp1ffz.cloudfront.net,🎬国外媒体 794 | DOMAIN,dfp6rglgjqszk.cloudfront.net,🎬国外媒体 795 | USER-AGENT,com.google.ios.youtube*,🎬国外媒体 796 | USER-AGENT,YouTube*,🎬国外媒体 797 | DOMAIN-SUFFIX,googlevideo.com,🎬国外媒体 798 | DOMAIN-SUFFIX,youtube.com,🎬国外媒体 799 | DOMAIN,youtubei.googleapis.com,🎬国外媒体 800 | 801 | DOMAIN-SUFFIX,local,DIRECT 802 | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve 803 | IP-CIDR,10.0.0.0/8,DIRECT,no-resolve 804 | IP-CIDR,172.16.0.0/12,DIRECT,no-resolve 805 | IP-CIDR,127.0.0.0/8,DIRECT,no-resolve 806 | IP-CIDR,100.64.0.0/10,DIRECT,no-resolve 807 | IP-CIDR6,::1/128,DIRECT,no-resolve 808 | IP-CIDR6,fc00::/7,DIRECT,no-resolve 809 | IP-CIDR6,fe80::/10,DIRECT,no-resolve 810 | IP-CIDR6,fd00::/8,DIRECT,no-resolve 811 | USER-AGENT,coffeecorp*,DIRECT 812 | USER-AGENT,restaurant-mobile*,DIRECT 813 | DOMAIN,app.adjust.com,DIRECT 814 | DOMAIN-SUFFIX,googletraveladservices.com,DIRECT 815 | DOMAIN,dl.google.com,DIRECT 816 | DOMAIN,mtalk.google.com,DIRECT 817 | DOMAIN,livew.l.qq.com,DIRECT 818 | DOMAIN,vd.l.qq.com,DIRECT 819 | DOMAIN,analytics.strava.com,DIRECT 820 | DOMAIN,msg.umeng.com,DIRECT 821 | DOMAIN,msg.umengcloud.com,DIRECT 822 | DOMAIN-SUFFIX,qhres.com,DIRECT 823 | DOMAIN-SUFFIX,qhimg.com,DIRECT 824 | DOMAIN-SUFFIX,akadns.net,DIRECT 825 | USER-AGENT,%E4%BC%98%E9%85%B7*,DIRECT 826 | DOMAIN-SUFFIX,alibaba.com,DIRECT 827 | DOMAIN-SUFFIX,alicdn.com,DIRECT 828 | DOMAIN-SUFFIX,alikunlun.com,DIRECT 829 | DOMAIN-SUFFIX,alipay.com,DIRECT 830 | DOMAIN-SUFFIX,amap.com,DIRECT 831 | DOMAIN-SUFFIX,autonavi.com,DIRECT 832 | DOMAIN-SUFFIX,dingtalk.com,DIRECT 833 | DOMAIN-SUFFIX,mxhichina.com,DIRECT 834 | DOMAIN-SUFFIX,soku.com,DIRECT 835 | DOMAIN-SUFFIX,taobao.com,DIRECT 836 | DOMAIN-SUFFIX,tmall.com,DIRECT 837 | DOMAIN-SUFFIX,tmall.hk,DIRECT 838 | DOMAIN-SUFFIX,ykimg.com,DIRECT 839 | DOMAIN-SUFFIX,youku.com,DIRECT 840 | DOMAIN-SUFFIX,xiami.com,DIRECT 841 | DOMAIN-SUFFIX,xiami.net,DIRECT 842 | DOMAIN-SUFFIX,aaplimg.com,DIRECT 843 | DOMAIN-SUFFIX,apple.co,DIRECT 844 | DOMAIN-SUFFIX,apple.com,DIRECT 845 | DOMAIN-SUFFIX,apple-cloudkit.com,DIRECT 846 | DOMAIN-SUFFIX,appstore.com,DIRECT 847 | DOMAIN-SUFFIX,cdn-apple.com,DIRECT 848 | DOMAIN-SUFFIX,crashlytics.com,DIRECT 849 | DOMAIN-SUFFIX,icloud.com,DIRECT 850 | DOMAIN-SUFFIX,icloud-content.com,DIRECT 851 | DOMAIN-SUFFIX,me.com,DIRECT 852 | DOMAIN-SUFFIX,mzstatic.com,DIRECT 853 | DOMAIN,www-cdn.icloud.com.akadns.net,DIRECT 854 | DOMAIN-SUFFIX,baidu.com,DIRECT 855 | DOMAIN-SUFFIX,baidubcr.com,DIRECT 856 | DOMAIN-SUFFIX,bdstatic.com,DIRECT 857 | DOMAIN-SUFFIX,yunjiasu-cdn.net,DIRECT 858 | DOMAIN-SUFFIX,acgvideo.com,DIRECT 859 | DOMAIN-SUFFIX,biliapi.com,DIRECT 860 | DOMAIN-SUFFIX,biliapi.net,DIRECT 861 | DOMAIN-SUFFIX,bilibili.com,DIRECT 862 | DOMAIN-SUFFIX,bilibili.tv,DIRECT 863 | DOMAIN-SUFFIX,hdslb.com,DIRECT 864 | DOMAIN-SUFFIX,blizzard.com,DIRECT 865 | DOMAIN-SUFFIX,battle.net,DIRECT 866 | DOMAIN,blzddist1-a.akamaihd.net,DIRECT 867 | DOMAIN-SUFFIX,feiliao.com,DIRECT 868 | DOMAIN-SUFFIX,pstatp.com,DIRECT 869 | DOMAIN-SUFFIX,snssdk.com,DIRECT 870 | DOMAIN-SUFFIX,iesdouyin.com,DIRECT 871 | DOMAIN-SUFFIX,toutiao.com,DIRECT 872 | DOMAIN-SUFFIX,cctv.com,DIRECT 873 | DOMAIN-SUFFIX,cctvpic.com,DIRECT 874 | DOMAIN-SUFFIX,livechina.com,DIRECT 875 | DOMAIN-SUFFIX,didialift.com,DIRECT 876 | DOMAIN-SUFFIX,didiglobal.com,DIRECT 877 | DOMAIN-SUFFIX,udache.com,DIRECT 878 | DOMAIN-SUFFIX,343480.com,DIRECT 879 | DOMAIN-SUFFIX,baduziyuan.com,DIRECT 880 | DOMAIN-SUFFIX,com-hs-hkdy.com,DIRECT 881 | DOMAIN-SUFFIX,czybjz.com,DIRECT 882 | DOMAIN-SUFFIX,dandanzan.com,DIRECT 883 | DOMAIN-SUFFIX,fjhps.com,DIRECT 884 | DOMAIN-SUFFIX,kuyunbo.club,DIRECT 885 | DOMAIN-SUFFIX,21cn.com,DIRECT 886 | DOMAIN-SUFFIX,hitv.com,DIRECT 887 | DOMAIN-SUFFIX,mgtv.com,DIRECT 888 | DOMAIN-SUFFIX,iqiyi.com,DIRECT 889 | DOMAIN-SUFFIX,iqiyipic.com,DIRECT 890 | DOMAIN-SUFFIX,71.am.com,DIRECT 891 | DOMAIN-SUFFIX,jd.com,DIRECT 892 | DOMAIN-SUFFIX,jd.hk,DIRECT 893 | DOMAIN-SUFFIX,jdpay.com,DIRECT 894 | DOMAIN-SUFFIX,360buyimg.com,DIRECT 895 | DOMAIN-SUFFIX,iciba.com,DIRECT 896 | DOMAIN-SUFFIX,ksosoft.com,DIRECT 897 | DOMAIN-SUFFIX,meitu.com,DIRECT 898 | DOMAIN-SUFFIX,meitudata.com,DIRECT 899 | DOMAIN-SUFFIX,meitustat.com,DIRECT 900 | DOMAIN-SUFFIX,meipai.com,DIRECT 901 | DOMAIN-SUFFIX,duokan.com,DIRECT 902 | DOMAIN-SUFFIX,mi-img.com,DIRECT 903 | DOMAIN-SUFFIX,miui.com,DIRECT 904 | DOMAIN-SUFFIX,miwifi.com,DIRECT 905 | DOMAIN-SUFFIX,xiaomi.com,DIRECT 906 | DOMAIN-SUFFIX,microsoft.com,DIRECT 907 | DOMAIN-SUFFIX,msecnd.net,DIRECT 908 | DOMAIN-SUFFIX,office365.com,DIRECT 909 | DOMAIN-SUFFIX,outlook.com,DIRECT 910 | DOMAIN-SUFFIX,s-microsoft.com,DIRECT 911 | DOMAIN-SUFFIX,visualstudio.com,DIRECT 912 | DOMAIN-SUFFIX,windows.com,DIRECT 913 | DOMAIN-SUFFIX,windowsupdate.com,DIRECT 914 | DOMAIN,officecdn-microsoft-com.akamaized.net,DIRECT 915 | USER-AGENT,NeteaseMusic*,DIRECT 916 | USER-AGENT,%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90*,DIRECT 917 | DOMAIN-SUFFIX,163.com,DIRECT 918 | DOMAIN-SUFFIX,126.net,DIRECT 919 | DOMAIN-SUFFIX,127.net,DIRECT 920 | DOMAIN-SUFFIX,163yun.com,DIRECT 921 | DOMAIN-SUFFIX,lofter.com,DIRECT 922 | DOMAIN-SUFFIX,netease.com,DIRECT 923 | DOMAIN-SUFFIX,ydstatic.com,DIRECT 924 | DOMAIN-SUFFIX,sina.com,DIRECT 925 | DOMAIN-SUFFIX,weibo.com,DIRECT 926 | DOMAIN-SUFFIX,weibocdn.com,DIRECT 927 | DOMAIN-SUFFIX,sohu.com,DIRECT 928 | DOMAIN-SUFFIX,sohucs.com,DIRECT 929 | DOMAIN-SUFFIX,sohu-inc.com,DIRECT 930 | DOMAIN-SUFFIX,v-56.com,DIRECT 931 | DOMAIN-SUFFIX,sogo.com,DIRECT 932 | DOMAIN-SUFFIX,sogou.com,DIRECT 933 | DOMAIN-SUFFIX,sogoucdn.com,DIRECT 934 | DOMAIN-SUFFIX,steampowered.com,DIRECT 935 | DOMAIN-SUFFIX,steam-chat.com,DIRECT 936 | DOMAIN-SUFFIX,steamgames.com,DIRECT 937 | DOMAIN-SUFFIX,steamusercontent.com,DIRECT 938 | DOMAIN-SUFFIX,steamcontent.com,DIRECT 939 | DOMAIN-SUFFIX,steamstatic.com,DIRECT 940 | DOMAIN-SUFFIX,steamcdn-a.akamaihd.net,DIRECT 941 | DOMAIN-SUFFIX,steamstat.us,DIRECT 942 | USER-AGENT,MicroMessenger%20Client,DIRECT 943 | USER-AGENT,WeChat*,DIRECT 944 | DOMAIN-SUFFIX,gtimg.com,DIRECT 945 | DOMAIN-SUFFIX,idqqimg.com,DIRECT 946 | DOMAIN-SUFFIX,igamecj.com,DIRECT 947 | DOMAIN-SUFFIX,myapp.com,DIRECT 948 | DOMAIN-SUFFIX,myqcloud.com,DIRECT 949 | DOMAIN-SUFFIX,qq.com,DIRECT 950 | DOMAIN-SUFFIX,tencent.com,DIRECT 951 | DOMAIN-SUFFIX,tencent-cloud.net,DIRECT 952 | USER-AGENT,YYeTs*,DIRECT 953 | DOMAIN-SUFFIX,jstucdn.com,DIRECT 954 | DOMAIN-SUFFIX,zimuzu.io,DIRECT 955 | DOMAIN-SUFFIX,zimuzu.tv,DIRECT 956 | DOMAIN-SUFFIX,zmz2019.com,DIRECT 957 | DOMAIN-SUFFIX,zmzapi.com,DIRECT 958 | DOMAIN-SUFFIX,zmzapi.net,DIRECT 959 | DOMAIN-SUFFIX,zmzfile.com,DIRECT 960 | DOMAIN-SUFFIX,ccgslb.com,DIRECT 961 | DOMAIN-SUFFIX,ccgslb.net,DIRECT 962 | DOMAIN-SUFFIX,chinanetcenter.com,DIRECT 963 | DOMAIN-SUFFIX,meixincdn.com,DIRECT 964 | DOMAIN-SUFFIX,ourdvs.com,DIRECT 965 | DOMAIN-SUFFIX,staticdn.net,DIRECT 966 | DOMAIN-SUFFIX,wangsu.com,DIRECT 967 | DOMAIN-SUFFIX,ipip.net,DIRECT 968 | DOMAIN-SUFFIX,ip.la,DIRECT 969 | DOMAIN-SUFFIX,ip-cdn.com,DIRECT 970 | DOMAIN-SUFFIX,ipv6-test.com,DIRECT 971 | DOMAIN-SUFFIX,test-ipv6.com,DIRECT 972 | DOMAIN-SUFFIX,whatismyip.com,DIRECT 973 | DOMAIN-SUFFIX,netspeedtestmaster.com,DIRECT 974 | DOMAIN,speedtest.macpaw.com,DIRECT 975 | DOMAIN-SUFFIX,awesome-hd.me,DIRECT 976 | DOMAIN-SUFFIX,broadcasthe.net,DIRECT 977 | DOMAIN-SUFFIX,chdbits.co,DIRECT 978 | DOMAIN-SUFFIX,classix-unlimited.co.uk,DIRECT 979 | DOMAIN-SUFFIX,empornium.me,DIRECT 980 | DOMAIN-SUFFIX,gazellegames.net,DIRECT 981 | DOMAIN-SUFFIX,hdchina.org,DIRECT 982 | DOMAIN-SUFFIX,hdsky.me,DIRECT 983 | DOMAIN-SUFFIX,icetorrent.org,DIRECT 984 | DOMAIN-SUFFIX,jpopsuki.eu,DIRECT 985 | DOMAIN-SUFFIX,keepfrds.com,DIRECT 986 | DOMAIN-SUFFIX,madsrevolution.net,DIRECT 987 | DOMAIN-SUFFIX,m-team.cc,DIRECT 988 | DOMAIN-SUFFIX,nanyangpt.com,DIRECT 989 | DOMAIN-SUFFIX,ncore.cc,DIRECT 990 | DOMAIN-SUFFIX,open.cd,DIRECT 991 | DOMAIN-SUFFIX,ourbits.club,DIRECT 992 | DOMAIN-SUFFIX,passthepopcorn.me,DIRECT 993 | DOMAIN-SUFFIX,privatehd.to,DIRECT 994 | DOMAIN-SUFFIX,redacted.ch,DIRECT 995 | DOMAIN-SUFFIX,springsunday.net,DIRECT 996 | DOMAIN-SUFFIX,tjupt.org,DIRECT 997 | DOMAIN-SUFFIX,totheglory.im,DIRECT 998 | DOMAIN-SUFFIX,acm.org,DIRECT 999 | DOMAIN-SUFFIX,acs.org,DIRECT 1000 | DOMAIN-SUFFIX,aip.org,DIRECT 1001 | DOMAIN-SUFFIX,ams.org,DIRECT 1002 | DOMAIN-SUFFIX,annualreviews.org,DIRECT 1003 | DOMAIN-SUFFIX,aps.org,DIRECT 1004 | DOMAIN-SUFFIX,ascelibrary.org,DIRECT 1005 | DOMAIN-SUFFIX,asm.org,DIRECT 1006 | DOMAIN-SUFFIX,asme.org,DIRECT 1007 | DOMAIN-SUFFIX,astm.org,DIRECT 1008 | DOMAIN-SUFFIX,bmj.com,DIRECT 1009 | DOMAIN-SUFFIX,cambridge.org,DIRECT 1010 | DOMAIN-SUFFIX,cas.org,DIRECT 1011 | DOMAIN-SUFFIX,clarivate.com,DIRECT 1012 | DOMAIN-SUFFIX,ebscohost.com,DIRECT 1013 | DOMAIN-SUFFIX,emerald.com,DIRECT 1014 | DOMAIN-SUFFIX,engineeringvillage.com,DIRECT 1015 | DOMAIN-SUFFIX,icevirtuallibrary.com,DIRECT 1016 | DOMAIN-SUFFIX,ieee.org,DIRECT 1017 | DOMAIN-SUFFIX,imf.org,DIRECT 1018 | DOMAIN-SUFFIX,iop.org,DIRECT 1019 | DOMAIN-SUFFIX,jamanetwork.com,DIRECT 1020 | DOMAIN-SUFFIX,jhu.edu,DIRECT 1021 | DOMAIN-SUFFIX,jstor.org,DIRECT 1022 | DOMAIN-SUFFIX,karger.com,DIRECT 1023 | DOMAIN-SUFFIX,libguides.com,DIRECT 1024 | DOMAIN-SUFFIX,madsrevolution.net,DIRECT 1025 | DOMAIN-SUFFIX,mpg.de,DIRECT 1026 | DOMAIN-SUFFIX,myilibrary.com,DIRECT 1027 | DOMAIN-SUFFIX,nature.com,DIRECT 1028 | DOMAIN-SUFFIX,oecd-ilibrary.org,DIRECT 1029 | DOMAIN-SUFFIX,osapublishing.org,DIRECT 1030 | DOMAIN-SUFFIX,oup.com,DIRECT 1031 | DOMAIN-SUFFIX,ovid.com,DIRECT 1032 | DOMAIN-SUFFIX,oxfordartonline.com,DIRECT 1033 | DOMAIN-SUFFIX,oxfordbibliographies.com,DIRECT 1034 | DOMAIN-SUFFIX,oxfordmusiconline.com,DIRECT 1035 | DOMAIN-SUFFIX,pnas.org,DIRECT 1036 | DOMAIN-SUFFIX,proquest.com,DIRECT 1037 | DOMAIN-SUFFIX,rsc.org,DIRECT 1038 | DOMAIN-SUFFIX,sagepub.com,DIRECT 1039 | DOMAIN-SUFFIX,sciencedirect.com,DIRECT 1040 | DOMAIN-SUFFIX,sciencemag.org,DIRECT 1041 | DOMAIN-SUFFIX,scopus.com,DIRECT 1042 | DOMAIN-SUFFIX,siam.org,DIRECT 1043 | DOMAIN-SUFFIX,spiedigitallibrary.org,DIRECT 1044 | DOMAIN-SUFFIX,springer.com,DIRECT 1045 | DOMAIN-SUFFIX,springerlink.com,DIRECT 1046 | DOMAIN-SUFFIX,tandfonline.com,DIRECT 1047 | DOMAIN-SUFFIX,un.org,DIRECT 1048 | DOMAIN-SUFFIX,uni-bielefeld.de,DIRECT 1049 | DOMAIN-SUFFIX,webofknowledge.com,DIRECT 1050 | DOMAIN-SUFFIX,westlaw.com,DIRECT 1051 | DOMAIN-SUFFIX,wiley.com,DIRECT 1052 | DOMAIN-SUFFIX,worldbank.org,DIRECT 1053 | DOMAIN-SUFFIX,worldscientific.com,DIRECT 1054 | DOMAIN-SUFFIX,cn,DIRECT 1055 | DOMAIN-SUFFIX,360in.com,DIRECT 1056 | DOMAIN-SUFFIX,51ym.me,DIRECT 1057 | DOMAIN-SUFFIX,8686c.com,DIRECT 1058 | DOMAIN-SUFFIX,abchina.com,DIRECT 1059 | DOMAIN-SUFFIX,accuweather.com,DIRECT 1060 | DOMAIN-SUFFIX,aicoinstorge.com,DIRECT 1061 | DOMAIN-SUFFIX,air-matters.com,DIRECT 1062 | DOMAIN-SUFFIX,air-matters.io,DIRECT 1063 | DOMAIN-SUFFIX,aixifan.com,DIRECT 1064 | DOMAIN-SUFFIX,amd.com,DIRECT 1065 | DOMAIN-SUFFIX,b612.net,DIRECT 1066 | DOMAIN-SUFFIX,bdatu.com,DIRECT 1067 | DOMAIN-SUFFIX,beitaichufang.com,DIRECT 1068 | DOMAIN-SUFFIX,bjango.com,DIRECT 1069 | DOMAIN-SUFFIX,booking.com,DIRECT 1070 | DOMAIN-SUFFIX,bstatic.com,DIRECT 1071 | DOMAIN-SUFFIX,cailianpress.com,DIRECT 1072 | DOMAIN-SUFFIX,camera360.com,DIRECT 1073 | DOMAIN-SUFFIX,chinaso.com,DIRECT 1074 | DOMAIN-SUFFIX,chua.pro,DIRECT 1075 | DOMAIN-SUFFIX,chuimg.com,DIRECT 1076 | DOMAIN-SUFFIX,chunyu.mobi,DIRECT 1077 | DOMAIN-SUFFIX,chushou.tv,DIRECT 1078 | DOMAIN-SUFFIX,cmbchina.com,DIRECT 1079 | DOMAIN-SUFFIX,cmbimg.com,DIRECT 1080 | DOMAIN-SUFFIX,ctrip.com,DIRECT 1081 | DOMAIN-SUFFIX,dfcfw.com,DIRECT 1082 | DOMAIN-SUFFIX,docschina.org,DIRECT 1083 | DOMAIN-SUFFIX,douban.com,DIRECT 1084 | DOMAIN-SUFFIX,doubanio.com,DIRECT 1085 | DOMAIN-SUFFIX,douyu.com,DIRECT 1086 | DOMAIN-SUFFIX,dxycdn.com,DIRECT 1087 | DOMAIN-SUFFIX,dytt8.net,DIRECT 1088 | DOMAIN-SUFFIX,eastmoney.com,DIRECT 1089 | DOMAIN-SUFFIX,eudic.net,DIRECT 1090 | DOMAIN-SUFFIX,feng.com,DIRECT 1091 | DOMAIN-SUFFIX,fengkongcloud.com,DIRECT 1092 | DOMAIN-SUFFIX,frdic.com,DIRECT 1093 | DOMAIN-SUFFIX,futu5.com,DIRECT 1094 | DOMAIN-SUFFIX,futunn.com,DIRECT 1095 | DOMAIN-SUFFIX,gandi.net,DIRECT 1096 | DOMAIN-SUFFIX,geilicdn.com,DIRECT 1097 | DOMAIN-SUFFIX,getpricetag.com,DIRECT 1098 | DOMAIN-SUFFIX,gifshow.com,DIRECT 1099 | DOMAIN-SUFFIX,godic.net,DIRECT 1100 | DOMAIN-SUFFIX,hicloud.com,DIRECT 1101 | DOMAIN-SUFFIX,hongxiu.com,DIRECT 1102 | DOMAIN-SUFFIX,hostbuf.com,DIRECT 1103 | DOMAIN-SUFFIX,huxiucdn.com,DIRECT 1104 | DOMAIN-SUFFIX,huya.com,DIRECT 1105 | DOMAIN-SUFFIX,infinitynewtab.com,DIRECT 1106 | DOMAIN-SUFFIX,ithome.com,DIRECT 1107 | DOMAIN-SUFFIX,java.com,DIRECT 1108 | DOMAIN-SUFFIX,jidian.im,DIRECT 1109 | DOMAIN-SUFFIX,kaiyanapp.com,DIRECT 1110 | DOMAIN-SUFFIX,kaspersky-labs.com,DIRECT 1111 | DOMAIN-SUFFIX,keepcdn.com,DIRECT 1112 | DOMAIN-SUFFIX,kkmh.com,DIRECT 1113 | DOMAIN-SUFFIX,licdn.com,DIRECT 1114 | DOMAIN-SUFFIX,linkedin.com,DIRECT 1115 | DOMAIN-SUFFIX,loli.net,DIRECT 1116 | DOMAIN-SUFFIX,luojilab.com,DIRECT 1117 | DOMAIN-SUFFIX,maoyan.com,DIRECT 1118 | DOMAIN-SUFFIX,maoyun.tv,DIRECT 1119 | DOMAIN-SUFFIX,meituan.com,DIRECT 1120 | DOMAIN-SUFFIX,meituan.net,DIRECT 1121 | DOMAIN-SUFFIX,mobike.com,DIRECT 1122 | DOMAIN-SUFFIX,moke.com,DIRECT 1123 | DOMAIN-SUFFIX,mubu.com,DIRECT 1124 | DOMAIN-SUFFIX,myzaker.com,DIRECT 1125 | DOMAIN-SUFFIX,nim-lang-cn.org,DIRECT 1126 | DOMAIN-SUFFIX,nvidia.com,DIRECT 1127 | DOMAIN-SUFFIX,oracle.com,DIRECT 1128 | DOMAIN-SUFFIX,paypal.com,DIRECT 1129 | DOMAIN-SUFFIX,paypalobjects.com,DIRECT 1130 | DOMAIN-SUFFIX,qdaily.com,DIRECT 1131 | DOMAIN-SUFFIX,qidian.com,DIRECT 1132 | DOMAIN-SUFFIX,qyer.com,DIRECT 1133 | DOMAIN-SUFFIX,qyerstatic.com,DIRECT 1134 | DOMAIN-SUFFIX,raychase.net,DIRECT 1135 | DOMAIN-SUFFIX,ronghub.com,DIRECT 1136 | DOMAIN-SUFFIX,ruguoapp.com,DIRECT 1137 | DOMAIN-SUFFIX,s-reader.com,DIRECT 1138 | DOMAIN-SUFFIX,sankuai.com,DIRECT 1139 | DOMAIN-SUFFIX,scomper.me,DIRECT 1140 | DOMAIN-SUFFIX,seafile.com,DIRECT 1141 | DOMAIN-SUFFIX,sm.ms,DIRECT 1142 | DOMAIN-SUFFIX,smzdm.com,DIRECT 1143 | DOMAIN-SUFFIX,snapdrop.net,DIRECT 1144 | DOMAIN-SUFFIX,snwx.com,DIRECT 1145 | DOMAIN-SUFFIX,sspai.com,DIRECT 1146 | DOMAIN-SUFFIX,takungpao.com,DIRECT 1147 | DOMAIN-SUFFIX,teamviewer.com,DIRECT 1148 | DOMAIN-SUFFIX,tianyancha.com,DIRECT 1149 | DOMAIN-SUFFIX,udacity.com,DIRECT 1150 | DOMAIN-SUFFIX,uning.com,DIRECT 1151 | DOMAIN-SUFFIX,vmware.com,DIRECT 1152 | DOMAIN-SUFFIX,weather.com,DIRECT 1153 | DOMAIN-SUFFIX,weico.cc,DIRECT 1154 | DOMAIN-SUFFIX,weidian.com,DIRECT 1155 | DOMAIN-SUFFIX,xiachufang.com,DIRECT 1156 | DOMAIN-SUFFIX,ximalaya.com,DIRECT 1157 | DOMAIN-SUFFIX,xinhuanet.com,DIRECT 1158 | DOMAIN-SUFFIX,xmcdn.com,DIRECT 1159 | DOMAIN-SUFFIX,yangkeduo.com,DIRECT 1160 | DOMAIN-SUFFIX,zhangzishi.cc,DIRECT 1161 | DOMAIN-SUFFIX,zhihu.com,DIRECT 1162 | DOMAIN-SUFFIX,zhimg.com,DIRECT 1163 | DOMAIN-SUFFIX,zhuihd.com,DIRECT 1164 | DOMAIN,download.jetbrains.com,DIRECT 1165 | DOMAIN,images-cn.ssl-images-amazon.com,DIRECT 1166 | IP-CIDR,119.28.28.28/32,DIRECT,no-resolve 1167 | GEOIP,CN,DIRECT 1168 | 1169 | FINAL,⚓️其他流量 1170 | -------------------------------------------------------------------------------- /Temp/pid.pid: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /appprofile.example.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'Checks' => [], 21 | 'General' => [ 22 | 'loglevel' => 'notify', 23 | 'dns-server' => 'system, 117.50.10.10, 119.29.29.29, 223.6.6.6', 24 | 'skip-proxy' => '127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 100.64.0.0/10, 17.0.0.0/8, localhost, *.local, *.crashlytics.com', 25 | 'external-controller-access' => 'China@0.0.0.0:8233', 26 | 'allow-wifi-access' => 'true', 27 | 'enhanced-mode-by-rule' => 'false', 28 | 'exclude-simple-hostnames' => 'true', 29 | 'show-error-page-for-reject' => 'true', 30 | 'ipv6' => 'true', 31 | 'replica' => 'false', 32 | 'http-listen' => '0.0.0.0:8234', 33 | 'socks5-listen' => '0.0.0.0:8235', 34 | 'wifi-access-http-port' => 6152, 35 | 'wifi-access-socks5-port' => 6153, 36 | 'internet-test-url' => 'http://baidu.com', 37 | 'proxy-test-url' => 'http://www.qualcomm.cn/generate_204', 38 | 'test-timeout' => 3 39 | ], 40 | 'Proxy' => [ 41 | '🚀直接连接 = direct' 42 | ], 43 | 'ProxyGroup' => [ 44 | [ 45 | 'name' => '🔰国外流量', 46 | 'type' => 'select', 47 | 'content' => [ 48 | 'regex' => '(.*)', 49 | 'right-proxies' => [ 50 | '🚀直接连接' 51 | ], 52 | ] 53 | ], 54 | [ 55 | 'name' => '⚓️其他流量', 56 | 'type' => 'select', 57 | 'content' => [ 58 | 'left-proxies' => [ 59 | '🔰国外流量', 60 | '🚀直接连接' 61 | ] 62 | ] 63 | ], 64 | [ 65 | 'name' => '✈️Telegram', 66 | 'type' => 'select', 67 | 'content' => [ 68 | 'left-proxies' => [ 69 | '🔰国外流量' 70 | ], 71 | 'regex' => '(.*)', 72 | ] 73 | ], 74 | [ 75 | 'name' => '🎬Youtube', 76 | 'type' => 'select', 77 | 'content' => [ 78 | 'left-proxies' => [ 79 | '🔰国外流量' 80 | ], 81 | 'regex' => '(.*)', 82 | ] 83 | ], 84 | [ 85 | 'name' => '🎬Netflix', 86 | 'type' => 'select', 87 | 'content' => [ 88 | 'left-proxies' => [ 89 | '🔰国外流量' 90 | ], 91 | 'regex' => '(.*)', 92 | ] 93 | ], 94 | [ 95 | 'name' => '🎬国外媒体', 96 | 'type' => 'select', 97 | 'content' => [ 98 | 'left-proxies' => [ 99 | '🔰国外流量' 100 | ], 101 | 'regex' => '(.*)', 102 | ] 103 | ], 104 | [ 105 | 'name' => '🍎苹果服务', 106 | 'type' => 'select', 107 | 'content' => [ 108 | 'left-proxies' => [ 109 | '🚀直接连接', 110 | '🔰国外流量' 111 | ] 112 | ] 113 | ] 114 | ], 115 | 'Rule' => [ 116 | 'source' => 'surge/default.tpl' 117 | ] 118 | ] 119 | ]; 120 | 121 | /** 122 | * Surge 2.x 版本的配置文件定义 123 | */ 124 | $_ENV['Surge2_Profiles'] = [ 125 | 'default' => [ 126 | 'Checks' => [], 127 | 'General' => [ 128 | 'loglevel' => 'notify', 129 | 'ipv6' => 'true', 130 | 'replica' => 'false', 131 | 'dns-server' => 'system, 119.29.29.29, 223.5.5.5', 132 | 'skip-proxy' => '127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 100.64.0.0/10, 17.0.0.0/8, localhost, *.local, *.crashlytics.com', 133 | 'bypass-system' => 'true', 134 | 'allow-wifi-access' => 'true', 135 | 'external-controller-access' => 'ChinaX@0.0.0.0:8233' 136 | ], 137 | 'Proxy' => [ 138 | '🚀直接连接 = direct' 139 | ], 140 | 'ProxyGroup' => [ 141 | [ 142 | 'name' => '🔰国外流量', 143 | 'type' => 'select', 144 | 'content' => [ 145 | 'regex' => '(.*)', 146 | 'right-proxies' => [ 147 | '🚀直接连接' 148 | ], 149 | ] 150 | ], 151 | [ 152 | 'name' => '⚓️其他流量', 153 | 'type' => 'select', 154 | 'content' => [ 155 | 'left-proxies' => [ 156 | '🔰国外流量', 157 | '🚀直接连接' 158 | ] 159 | ] 160 | ], 161 | [ 162 | 'name' => '✈️Telegram', 163 | 'type' => 'select', 164 | 'content' => [ 165 | 'left-proxies' => [ 166 | '🔰国外流量' 167 | ], 168 | 'regex' => '(.*)', 169 | ] 170 | ], 171 | [ 172 | 'name' => '🎬Youtube', 173 | 'type' => 'select', 174 | 'content' => [ 175 | 'left-proxies' => [ 176 | '🔰国外流量' 177 | ], 178 | 'regex' => '(.*)', 179 | ] 180 | ], 181 | [ 182 | 'name' => '🎬Netflix', 183 | 'type' => 'select', 184 | 'content' => [ 185 | 'left-proxies' => [ 186 | '🔰国外流量' 187 | ], 188 | 'regex' => '(.*)', 189 | ] 190 | ], 191 | [ 192 | 'name' => '🎬国外媒体', 193 | 'type' => 'select', 194 | 'content' => [ 195 | 'left-proxies' => [ 196 | '🔰国外流量' 197 | ], 198 | 'regex' => '(.*)', 199 | ] 200 | ], 201 | [ 202 | 'name' => '🍎苹果服务', 203 | 'type' => 'select', 204 | 'content' => [ 205 | 'left-proxies' => [ 206 | '🚀直接连接', 207 | '🔰国外流量' 208 | ] 209 | ] 210 | ] 211 | ], 212 | 'Rule' => [ 213 | 'source' => 'surge2/default.tpl' 214 | ] 215 | ] 216 | ]; 217 | 218 | /** 219 | * Clash 配置文件定义 220 | */ 221 | $_ENV['Clash_Profiles'] = [ 222 | 'default' => [ 223 | 'Checks' => [], 224 | 'General' => [ 225 | 'port' => 7890, 226 | 'socks-port' => 7891, 227 | 'redir-port' => 7892, 228 | 'allow-lan' => false, 229 | 'mode' => 'rule', 230 | 'log-level' => 'silent', 231 | 'external-controller' => '0.0.0.0:9090', 232 | 'secret' => '' 233 | ], 234 | 'Proxy' => [], 235 | 'ProxyGroup' => [ 236 | [ 237 | 'name' => '🔰国外流量', 238 | 'type' => 'select', 239 | 'content' => [ 240 | 'regex' => '(.*)', 241 | 'right-proxies' => [ 242 | '🚀直接连接' 243 | ], 244 | ] 245 | ], 246 | [ 247 | 'name' => '⚓️其他流量', 248 | 'type' => 'select', 249 | 'content' => [ 250 | 'left-proxies' => [ 251 | '🔰国外流量', 252 | '🚀直接连接' 253 | ] 254 | ] 255 | ], 256 | [ 257 | 'name' => '✈️Telegram', 258 | 'type' => 'select', 259 | 'content' => [ 260 | 'left-proxies' => [ 261 | '🔰国外流量' 262 | ], 263 | 'regex' => '(.*)', 264 | ] 265 | ], 266 | [ 267 | 'name' => '🎬Youtube', 268 | 'type' => 'select', 269 | 'content' => [ 270 | 'left-proxies' => [ 271 | '🔰国外流量' 272 | ], 273 | 'regex' => '(.*)', 274 | ] 275 | ], 276 | [ 277 | 'name' => '🎬Netflix', 278 | 'type' => 'select', 279 | 'content' => [ 280 | 'left-proxies' => [ 281 | '🔰国外流量' 282 | ], 283 | 'regex' => '(.*)', 284 | ] 285 | ], 286 | [ 287 | 'name' => '🎬国外媒体', 288 | 'type' => 'select', 289 | 'content' => [ 290 | 'left-proxies' => [ 291 | '🔰国外流量' 292 | ], 293 | 'regex' => '(.*)', 294 | ] 295 | ], 296 | [ 297 | 'name' => '🍎苹果服务', 298 | 'type' => 'select', 299 | 'content' => [ 300 | 'left-proxies' => [ 301 | '🚀直接连接', 302 | '🔰国外流量' 303 | ] 304 | ] 305 | ], 306 | [ 307 | 'name' => '🚀直接连接', 308 | 'type' => 'select', 309 | 'content' => [ 310 | 'left-proxies' => [ 311 | 'DIRECT' 312 | ] 313 | ] 314 | ] 315 | ], 316 | 'Rule' => [ 317 | 'source' => 'clash/default.tpl' 318 | ] 319 | ] 320 | ]; 321 | 322 | /** 323 | * Surfboard 配置文件定义 324 | */ 325 | $_ENV['Surfboard_Profiles'] = [ 326 | 'default' => [ 327 | 'Checks' => [], 328 | 'General' => [ 329 | 'loglevel' => 'notify', 330 | 'dns-server' => 'system, 119.29.29.29, 223.5.5.5', 331 | 'skip-proxy' => '127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 100.64.0.0/10, 17.0.0.0/8, localhost, *.local, *.crashlytics.com', 332 | ], 333 | 'Proxy' => [ 334 | '🚀直接连接 = direct' 335 | ], 336 | 'ProxyGroup' => [ 337 | [ 338 | 'name' => '🔰国外流量', 339 | 'type' => 'select', 340 | 'content' => [ 341 | 'regex' => '(.*)', 342 | 'right-proxies' => [ 343 | '🚀直接连接' 344 | ], 345 | ] 346 | ], 347 | [ 348 | 'name' => '⚓️其他流量', 349 | 'type' => 'select', 350 | 'content' => [ 351 | 'left-proxies' => [ 352 | '🔰国外流量', 353 | '🚀直接连接' 354 | ] 355 | ] 356 | ], 357 | [ 358 | 'name' => '✈️Telegram', 359 | 'type' => 'select', 360 | 'content' => [ 361 | 'left-proxies' => [ 362 | '🔰国外流量' 363 | ], 364 | 'regex' => '(.*)', 365 | ] 366 | ], 367 | [ 368 | 'name' => '🎬Youtube', 369 | 'type' => 'select', 370 | 'content' => [ 371 | 'left-proxies' => [ 372 | '🔰国外流量' 373 | ], 374 | 'regex' => '(.*)', 375 | ] 376 | ], 377 | [ 378 | 'name' => '🎬Netflix', 379 | 'type' => 'select', 380 | 'content' => [ 381 | 'left-proxies' => [ 382 | '🔰国外流量' 383 | ], 384 | 'regex' => '(.*)', 385 | ] 386 | ], 387 | [ 388 | 'name' => '🎬国外媒体', 389 | 'type' => 'select', 390 | 'content' => [ 391 | 'left-proxies' => [ 392 | '🔰国外流量' 393 | ], 394 | 'regex' => '(.*)', 395 | ] 396 | ] 397 | ], 398 | 'Rule' => [ 399 | 'source' => 'surfboard/default.tpl' 400 | ] 401 | ] 402 | ]; 403 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "easyswoole/easyswoole": "3.x", 4 | "illuminate/database": "^7.4", 5 | "voku/anti-xss": "^4.1", 6 | "symfony/yaml": "^5.0", 7 | "ramsey/uuid": "^4.0" 8 | }, 9 | "autoload": { 10 | "psr-4": { 11 | "App\\": "App/" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 'geekSubcribeX', 13 | 14 | // 站点地址 15 | 'baseUrl' => 'https://sspanel', 16 | 17 | // 订阅地址 18 | 'subUrl' => 'https://sspanel/link/', 19 | 20 | // 单端口多用户混淆参数后缀,可以随意修改,但请保持前后端一致 21 | 'mu_suffix' => 'microsoft.com', 22 | 23 | // 单端口多用户混淆参数表达式,%5m代表取用户特征 md5 的前五位,%id 代表用户id, %suffix 代表上面这个后缀 24 | 'mu_regex' => '%5m%id.%suffix', 25 | 26 | // 不安全中转模式,这个开启之后使用除了 auth_aes128_md5 或者 auth_aes128_sha1 以外的协议地用户也可以设置和使用中转 27 | 'relay_insecure_mode' => false, 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | 数据库配置 32 | |-------------------------------------------------------------------------- 33 | */ 34 | 35 | 'database' => [ 36 | 'driver' => 'mysql', 37 | 'host' => '127.0.0.1', 38 | 'port' => 3306, 39 | 'database' => 'sspanel', 40 | 'username' => 'sspanel', 41 | 'password' => 'sspanel', 42 | 'charset' => 'utf8', 43 | 'collation' => 'utf8_general_ci', 44 | 'prefix' => '' 45 | ], 46 | 47 | /* 48 | |-------------------------------------------------------------------------- 49 | | 订阅配置 50 | |-------------------------------------------------------------------------- 51 | */ 52 | 53 | 'SUB' => [ 54 | 55 | // 订阅记录 56 | 'Log' => false, 57 | 58 | // 合并订阅 59 | 'mergeSub' => true, 60 | 61 | // 订阅中的营销信息 62 | 'sub_message' => [], 63 | 64 | // 关闭 SS/SSR 单端口节点的端口显示 65 | 'disable_sub_mu_port' => true, 66 | 67 | // 为 SS 节点名称中添加站点名 68 | 'add_appName_to_ss_uri' => false, 69 | 70 | // Clash 默认配置方案 71 | 'Clash_DefaultProfiles' => 'default', 72 | 73 | // Surge 默认配置方案 74 | 'Surge_DefaultProfiles' => 'default', 75 | 76 | // Surge2 默认配置方案 77 | 'Surge2_DefaultProfiles' => 'default', 78 | 79 | // Surfboard 默认配置方案 80 | 'Surfboard_DefaultProfiles' => 'default', 81 | ], 82 | 83 | 84 | /* 85 | |-------------------------------------------------------------------------- 86 | | 服务配置 87 | |-------------------------------------------------------------------------- 88 | */ 89 | 90 | 'SERVER_NAME' => "geekSubcribeX", 91 | 'MAIN_SERVER' => [ 92 | 'LISTEN_ADDRESS' => '0.0.0.0', 93 | 'PORT' => 9501, 94 | 'SERVER_TYPE' => EASYSWOOLE_WEB_SERVER, //可选为 EASYSWOOLE_SERVER EASYSWOOLE_WEB_SERVER EASYSWOOLE_WEB_SOCKET_SERVER,EASYSWOOLE_REDIS_SERVER 95 | 'SOCK_TYPE' => SWOOLE_TCP, 96 | 'RUN_MODEL' => SWOOLE_PROCESS, 97 | 'SETTING' => [ 98 | 'worker_num' => 8, 99 | 'reload_async' => true, 100 | 'max_wait_time' => 3 101 | ], 102 | 'TASK' => [ 103 | 'workerNum' => 4, 104 | 'maxRunningNum' => 128, 105 | 'timeout' => 15 106 | ] 107 | ], 108 | 'TEMP_DIR' => null, 109 | 'LOG_DIR' => null, 110 | ]; 111 | -------------------------------------------------------------------------------- /easyswoole: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run($args); 46 | if (!empty($ret)) { 47 | echo $ret . "\n"; 48 | } 49 | 50 | 51 | --------------------------------------------------------------------------------