之前写了一次网站订阅中增加对新版clash的支持,同时支持旧版本,但是并没有写完,现在很多人在使用malio,clash也更新很久了。
所以本篇文章不再考虑是否支持旧版本,直接修改配置文件以支持新版
我在文章中标注了具体的行数,如果你是最后一版的malio,应该是一致的。
正文
一、修改配置模板
打开resources/conf/clash.tpl
定位到59行:
找到
Proxy:
修改为:
proxies:
定位到64行:
找到
Proxy Group:
修改为:
proxy-groups:
二、修改规则文件
打开resources/conf/rule/lhie1_Rule.yaml
修改第一行
Rule:
修改为:
rules:
三、修改节点参数模板
新版clash把ssr的obfsparam和protocolparam两个参数改成了obfs-param和protocol-param。修改 /app/Utils/AppURI.php,找到名为 getClashURI 的函数(175行)
找到(240行)
$return = [
'name' => $item['remark'],
'type' => 'ssr',
'server' => $item['address'],
'port' => $item['port'],
'cipher' => $item['method'],
'password' => $item['passwd'],
'protocol' => $item['protocol'],
'protocolparam' => $item['protocol_param'],
'obfs' => $item['obfs'],
'obfsparam' => $item['obfs_param']
];
break;
修改为
$return = [
'name' => $item['remark'],
'type' => 'ssr', 'server' => $item['address'],
'port' => $item['port'],
'cipher' => $item['method'],
'password' => $item['passwd'],
'protocol' => $item['protocol'],
'protocol-param' => $item['protocol_param'],
'obfs' => $item['obfs'],
'obfs-param' => $item['obfs_param']
];
break;
四、修改控制配置函数
打开app/Controllers/ConfController.php
将$tmp的键Proxy Group和Proxy改为proxy-groups和Proxies,或者直接替换下面的代码块(359行)
public static function getNewClashConfs($User, $AllProxys, $Configs, $local = false)
{
if (isset($Configs['Proxy']) || count($Configs['Proxy']) != 0) {
$tmpProxys = array_merge($AllProxys, $Configs['Proxy']);
} else {
$tmpProxys = $AllProxys;
}
$Proxys = [];
foreach ($tmpProxys as $Proxy) {
unset($Proxy['class']);
$Proxys[] = $Proxy;
}
$tmp = self::getClashConfGeneral($Configs['General']);
$tmp['Proxies'] = $Proxys;
if (isset($Configs['ProxyGroup'])) {
$tmp['proxy-groups'] = self::getClashConfProxyGroup(
$AllProxys,
$Configs['ProxyGroup']
);
} else {
$tmp['proxy-groups'] = self::getClashConfProxyGroup(
$AllProxys,
$Configs['Proxy Group']
);
}
$Conf = '#!MANAGED-CONFIG '
. Config::get('baseUrl') . $_SERVER['REQUEST_URI'] .
"\n\n#---------------------------------------------------#" .
"\n## 上次更新于:" . date("Y-m-d h:i:s") .
"\n#---------------------------------------------------#" .
"\n\n"
. Yaml::dump($tmp, 4, 2) .
"\n\n"
. self::getClashConfRule($Configs['Rule'], $local);
return $Conf;
}
五、修改控制文件
打开 app/Controllers/LinkController.php
文件
找到getClash代码块(在919行)
找到
$ssr_support = ($clash == 2 ? true : false);
修改为
$ssr_support = ($clash == 1 ? true : false);
随着clash内核升级到1.1并支持ssr以后,Windows版、MacOS版和Android版陆续跟进并支持ssr,从此带R版本的clash就退出历史舞台。略觉得美中不足的地方就是支持ssr后的clash内核不再向下兼容以前版本的参数,据作者所说是为了减少开发成本。那么如何让sspanel的订阅链接支持新版clash就是大家慢慢开始讨论的话题了,更甚者是让同一订阅链接支持新旧版clash的想法。
新版clash软件使用方法:
https://www.mebi.me/1609.html
前提
- 修改之前务必先备份
- 有一定动手能力
- 有php面向对象的基础
订阅支持新版clash
新增配置模板
clash配置模板在网站根目录下的 resources/conf/clash.tpl,复制一份 clash.tpl,重命名为 new_clash.tpl并打开,定位59行:
Proxy:
修改为:
proxies:
定位到64行:
Proxy Group:
修改为:
proxy-groups:
新增规则文件
clash规则文件在网站根目录下的 resources/conf/rule 目录里,复制一份 lhie1_Rule.yaml,重命名为 lhie1_New_Rule.yaml,打开 lhie1_New_Rule.yaml 文件定位到第一行:
Rule:
修改为:
rules:
新增节点参数模板
新版clash把ssr的obfsparam和protocolparam两个参数改成了obfs-param和protocol-param。修改 /app/Utils/AppURI.php,找到名为 getClashURI 的函数,复制粘贴此函数到它的下面,命名为 getNewClashURI,getNewClashURI 函数和 getClashRUI 函数唯一需要修改地方如下:
$return = [ 'name' => $item['remark'], 'type' => 'ssr', 'server' => $item['address'], 'port' => $item['port'], 'cipher' => $item['method'], 'password' => $item['passwd'], 'protocol' => $item['protocol'], 'protocolparam' => $item['protocol_param'], 'obfs' => $item['obfs'], 'obfsparam' => $item['obfs_param'] ]; break;
修改为:
$return = [ 'name' => $item['remark'], 'type' => 'ssr', 'server' => $item['address'], 'port' => $item['port'], 'cipher' => $item['method'], 'password' => $item['passwd'], 'protocol' => $item['protocol'], 'protocol-param' => $item['protocol_param'], 'obfs' => $item['obfs'], 'obfs-param' => $item['obfs_param'] ]; break;
修改控制配置函数
文件 app/Controllers/ConfController.php,复制 getClashConfs 函数重命名为 getNewClashConfs 函数,代码几乎一致,区别在$tmp的键Proxy Group和Proxy改为proxy-groups和Proxies。
public static function getNewClashConfs($User, $AllProxys, $Configs, $local = false) { if (isset($Configs['Proxy']) || count($Configs['Proxy']) != 0) { $tmpProxys = array_merge($AllProxys, $Configs['Proxy']); } else { $tmpProxys = $AllProxys; } $Proxys = []; foreach ($tmpProxys as $Proxy) { unset($Proxy['class']); $Proxys[] = $Proxy; } $tmp = self::getClashConfGeneral($Configs['General']); $tmp['Proxies'] = $Proxys; if (isset($Configs['ProxyGroup'])) { $tmp['proxy-groups'] = self::getClashConfProxyGroup( $AllProxys, $Configs['ProxyGroup'] ); } else { $tmp['proxy-groups'] = self::getClashConfProxyGroup( $AllProxys, $Configs['Proxy Group'] ); } $Conf = '#!MANAGED-CONFIG ' . Config::get('baseUrl') . $_SERVER['REQUEST_URI'] . "\n\n#---------------------------------------------------#" . "\n## 上次更新于:" . date("Y-m-d h:i:s") . "\n#---------------------------------------------------#" . "\n\n" . Yaml::dump($tmp, 4, 2) . "\n\n" . self::getClashConfRule($Configs['Rule'], $local); return $Conf; }
修改控制文件
打开 app/Controllers/LinkController.php 文件,找到名为 getClash 的函数,首先我们判断订阅链接是否带有new=1的参数,如果有表示请求新版clash订阅链接,用上面添加的 getNewClashURI 函数获取节点的参数和信息,无则表示请求旧版clash订阅链接,使用原来的 getClashURI 函数获取节点的参数和信息。
getClash函数中找到如下代码
foreach ($items as $item) { $Proxy = AppURI::getClashURI($item, $ssr_support); if ($Proxy !== null) { if (isset($opts['source']) && $opts['source'] != '') { $Proxy['class'] = $item['class']; } $Proxys[] = $Proxy; } }
修改为
if (isset($opts['new']) && $opts['new'] == 1) { foreach ($items as $item) { $Proxy = AppURI::getNewClashURI($item, true); if ($Proxy !== null) { if (isset($opts['source']) && $opts['source'] != '') { $Proxy['class'] = $item['class']; } $Proxys[] = $Proxy; } } }else{ foreach ($items as $item) { $Proxy = AppURI::getClashURI($item, $ssr_support); if ($Proxy !== null) { if (isset($opts['source']) && $opts['source'] != '') { $Proxy['class'] = $item['class']; } $Proxys[] = $Proxy; } } }
找到
return ConfController::getClashConfs( $user, $Proxys, $Content );
修改为:
if (isset($opts['new']) && $opts['new'] == 1) { return ConfController::getNewClashConfs( $user, $Proxys, $Content ); }else{ return ConfController::getClashConfs( $user, $Proxys, $Content ); }
找到:
return $render->fetch('clash.tpl');
修改为:
if (isset($opts['new']) && $opts['new'] == 1) { return $render->fetch('new_clash.tpl'); }else{ return $render->fetch('clash.tpl'); }
好了完工。在原来的clash订阅链接最后加上参数:&new=1,此链接可适用于新版clash。如果不加参数就适用旧版clash。
兼容新旧版clash
两个订阅其实用户还是有一定选择困难的,几乎没人知道自己的clash是否是“新版”。那么使用同一订阅链接兼容新旧版clash会有更好的适用性。
还是在 LinkController.php 文件的getClash函数,我们需要判断clash的user-agent返回的版本号来确定用户此时正在使用的是旧版还是新版clash,并给出相应的订阅内容。
另外还需要清楚新旧版的版本号“分界线”:ClashforWindows是0.11.2;ClashForAndroid是2.1.1;ClashX是1.30.0;linux判断没有意义。ClashforWindows的user-agent特殊,早期版本没有ClashforWindows,然后到0.11.0版本之前一直是ClashforWindows/7.0,0.11.0版本才开始有正式格式:ClashforWindows/version,所以我们要注意判断。
//兼容新旧版clash $clash_new = false; $agent_arr = explode('/', $request->getHeaderLine('User-Agent')); $clash_agent = $agent_arr[0]; $clash_version = explode(' ', $agent_arr[1])[0]; if (strstr($clash_agent, 'ClashforWindows')) { if ($clash_version >= "0.11.2" && $clash_version != "7.0") { $clash_new = true; } } if (strstr($clash_agent, 'ClashForAndroid')) { if ($clash_version >= "2.1.1") { $clash_new = true; } } if (strstr($clash_agent, 'ClashX')) { if ($clash_version >= "1.30.0") { $clash_new = true; } }
这段代码需要跟上面的搭配,但是不需要参数new了,自己适当修改修改。这段代码引入了函数参数$request,原来代码中这个参数在函数间不传递,那么我们就要增加这个参数。
找到GetContent函数,这是一个订阅的入口函数。找到如下代码
$content = self::$class($user, $query_value, $opts, $Rule);
此代码一共有两处,都需要修改。修改为
$content = self::$class($user, $query_value, $request, $opts, $Rule);
然后把对应的函数的参数也加上$request。例如我们修改的getClash函数,原先为
public static function getClash($user, $clash, $opts, $Rule)
修改为
public static function getClash($user, $clash, $request, $opts, $Rule)
除了getClash函数外,还有getSSD、getShadowrocket等等。这些都必须修改,否则会因为传递参数数量不匹配,网页直接500错误。