Browse Source

update: support stash

tokumeikoi 3 years ago
parent
commit
333611da48
2 changed files with 159 additions and 0 deletions
  1. 159 0
      app/Http/Controllers/Client/Protocols/Stash.php
  2. 0 0
      public/theme/v2board/assets/umi.js

+ 159 - 0
app/Http/Controllers/Client/Protocols/Stash.php

@@ -0,0 +1,159 @@
+<?php
+
+namespace App\Http\Controllers\Client\Protocols;
+
+use Symfony\Component\Yaml\Yaml;
+
+class Stash
+{
+    public $flag = 'stash';
+    private $servers;
+    private $user;
+
+    public function __construct($user, $servers)
+    {
+        $this->user = $user;
+        $this->servers = $servers;
+    }
+
+    public function handle()
+    {
+        $servers = $this->servers;
+        $user = $this->user;
+        $appName = config('v2board.app_name', 'V2Board');
+        header("subscription-userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}; expire={$user['expired_at']}");
+        header('profile-update-interval: 24');
+        header("content-disposition: filename={$appName}");
+        // 暂时使用clash配置文件,后续根据Stash更新情况更新
+        $defaultConfig = base_path() . '/resources/rules/default.clash.yaml';
+        $customConfig = base_path() . '/resources/rules/custom.clash.yaml';
+        if (\File::exists($customConfig)) {
+            $config = Yaml::parseFile($customConfig);
+        } else {
+            $config = Yaml::parseFile($defaultConfig);
+        }
+        $proxy = [];
+        $proxies = [];
+
+        foreach ($servers as $item) {
+            if ($item['type'] === 'shadowsocks') {
+                array_push($proxy, self::buildShadowsocks($user['uuid'], $item));
+                array_push($proxies, $item['name']);
+            }
+            if ($item['type'] === 'v2ray') {
+                array_push($proxy, self::buildVmess($user['uuid'], $item));
+                array_push($proxies, $item['name']);
+            }
+            if ($item['type'] === 'trojan') {
+                array_push($proxy, self::buildTrojan($user['uuid'], $item));
+                array_push($proxies, $item['name']);
+            }
+        }
+
+        $config['proxies'] = array_merge($config['proxies'] ? $config['proxies'] : [], $proxy);
+        foreach ($config['proxy-groups'] as $k => $v) {
+            if (!is_array($config['proxy-groups'][$k]['proxies'])) continue;
+            $isFilter = false;
+            foreach ($config['proxy-groups'][$k]['proxies'] as $srcProxie) {
+                foreach ($proxies as $dstProxie) {
+                    if ($this->isMatch($srcProxie, $dstProxie)) {
+                        $isFilter = true;
+                        $config['proxy-groups'][$k]['proxies'] = array_diff($config['proxy-groups'][$k]['proxies'], [$srcProxie]);
+                        array_push($config['proxy-groups'][$k]['proxies'], $dstProxie);
+                    }
+                }
+            }
+            if (!$isFilter) {
+                $config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxies);
+            }
+        }
+        // Force the current subscription domain to be a direct rule
+        $subsDomain = $_SERVER['SERVER_NAME'];
+        $subsDomainRule = "DOMAIN,{$subsDomain},DIRECT";
+        array_unshift($config['rules'], $subsDomainRule);
+
+        $yaml = Yaml::dump($config);
+        $yaml = str_replace('$app_name', config('v2board.app_name', 'V2Board'), $yaml);
+        return $yaml;
+    }
+
+    public static function buildShadowsocks($uuid, $server)
+    {
+        $array = [];
+        $array['name'] = $server['name'];
+        $array['type'] = 'ss';
+        $array['server'] = $server['host'];
+        $array['port'] = $server['port'];
+        $array['cipher'] = $server['cipher'];
+        $array['password'] = $uuid;
+        $array['udp'] = true;
+        return $array;
+    }
+
+    public static function buildVmess($uuid, $server)
+    {
+        $array = [];
+        $array['name'] = $server['name'];
+        $array['type'] = 'vmess';
+        $array['server'] = $server['host'];
+        $array['port'] = $server['port'];
+        $array['uuid'] = $uuid;
+        $array['alterId'] = $server['alter_id'];
+        $array['cipher'] = 'auto';
+        $array['udp'] = true;
+
+        if ($server['tls']) {
+            $array['tls'] = true;
+            if ($server['tlsSettings']) {
+                $tlsSettings = $server['tlsSettings'];
+                if (isset($tlsSettings['allowInsecure']) && !empty($tlsSettings['allowInsecure']))
+                    $array['skip-cert-verify'] = ($tlsSettings['allowInsecure'] ? true : false);
+                if (isset($tlsSettings['serverName']) && !empty($tlsSettings['serverName']))
+                    $array['servername'] = $tlsSettings['serverName'];
+            }
+        }
+        if ($server['network'] === 'ws') {
+            $array['network'] = 'ws';
+            if ($server['networkSettings']) {
+                $wsSettings = $server['networkSettings'];
+                if (isset($wsSettings['path']) && !empty($wsSettings['path']))
+                    $array['ws-path'] = $wsSettings['path'];
+                if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host']))
+                    $array['ws-headers'] = ['Host' => $wsSettings['headers']['Host']];
+            }
+        }
+        if ($server['network'] === 'grpc') {
+            $array['network'] = 'grpc';
+            if ($server['networkSettings']) {
+                $grpcObject = $server['networkSettings'];
+                $array['grpc-opts'] = [];
+                $array['grpc-opts']['grpc-service-name'] = $grpcObject['serviceName'];
+            }
+        }
+
+        return $array;
+    }
+
+    public static function buildTrojan($password, $server)
+    {
+        $array = [];
+        $array['name'] = $server['name'];
+        $array['type'] = 'trojan';
+        $array['server'] = $server['host'];
+        $array['port'] = $server['port'];
+        $array['password'] = $password;
+        $array['udp'] = true;
+        if (!empty($server['server_name'])) $array['sni'] = $server['server_name'];
+        if (!empty($server['allow_insecure'])) $array['skip-cert-verify'] = ($server['allow_insecure'] ? true : false);
+        return $array;
+    }
+
+    private function isMatch($exp, $str)
+    {
+        try {
+            return preg_match($exp, $str);
+        } catch (\Exception $e) {
+            return false;
+        }
+    }
+}

File diff suppressed because it is too large
+ 0 - 0
public/theme/v2board/assets/umi.js


Some files were not shown because too many files changed in this diff