no message
This commit is contained in:
parent
50085246b1
commit
f06a42da73
59
app/Http/Controllers/SakaiFnController.php
Executable file
59
app/Http/Controllers/SakaiFnController.php
Executable file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
//use Illuminate\Http\Request;
|
||||
//use App\Models\ArticleList;
|
||||
//use App\Services\Time;
|
||||
//use voku\helper\AntiXSS;
|
||||
//use App\Models\Tags;
|
||||
//use App\Services\TomTool\Http;
|
||||
//use App\Services\CountrySpeedService;
|
||||
//use App\Services\ServiceFnPoolV2rayTo;
|
||||
//use App\Models\FreenodePool as ModelFreenodePool;
|
||||
//use App\Services\Cron\ReportTraffic;
|
||||
use App\Models\FreenodePool;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SakaiFnController
|
||||
{
|
||||
public function looktrans(Request $oRequest, string $sClient = "singbox", string $sXieyi, ?string $sLike = '')
|
||||
{
|
||||
$sDate = date("Y-m-d");
|
||||
$sContent = FreenodePool::whereDate("date", $sDate)->first()?->content;
|
||||
$aContent = json_decode($sContent, true);
|
||||
|
||||
$cClientContent = $aContent[$sClient];
|
||||
|
||||
$aNode = [];
|
||||
|
||||
if ($sClient == "singbox") {
|
||||
foreach ($cClientContent as $sMd5 => $aClientContent) {
|
||||
|
||||
$sContentXieyi = $aClientContent["protocolType"] ?? '';
|
||||
|
||||
if ($sXieyi != "all" && $sContentXieyi != $sXieyi) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sNodeName = $aClientContent["country"];
|
||||
|
||||
if ($sLike) {
|
||||
if (!Str::contains($sNodeName, $sLike, true)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$aNode[] = $aClientContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tt($aNode);
|
||||
// tt($aContent[$sClient]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -86,7 +86,7 @@ class ServiceFnPoolV2rayTo
|
||||
return $aV2ray;
|
||||
}
|
||||
|
||||
private function mod_to_trojan($aV2ray)
|
||||
private function mod_to_trojan__($aV2ray)
|
||||
{
|
||||
$sConfig = $aV2ray["config"] ?? '';
|
||||
|
||||
@ -177,7 +177,7 @@ class ServiceFnPoolV2rayTo
|
||||
return $aV2ray;
|
||||
}
|
||||
|
||||
private function mod_to_hysteria2($aV2ray)
|
||||
private function mod_to_hysteria2__($aV2ray)
|
||||
{
|
||||
$sConfig = $aV2ray["config"] ?? '';
|
||||
|
||||
@ -237,7 +237,7 @@ class ServiceFnPoolV2rayTo
|
||||
return $aV2ray;
|
||||
}
|
||||
|
||||
private function mod_to_ss($aV2ray)
|
||||
private function mod_to_ss__($aV2ray)
|
||||
{
|
||||
$sConfig = $aV2ray["config"] ?? '';
|
||||
|
||||
@ -285,55 +285,138 @@ class ServiceFnPoolV2rayTo
|
||||
return $aV2ray;
|
||||
}
|
||||
|
||||
private function mod_to_vmess($aV2ray)
|
||||
private function mod_to_vmess(array $aV2ray): array
|
||||
{
|
||||
$aNode = [];
|
||||
$aConfig = $aV2ray["config"];
|
||||
|
||||
$aNode["type"] = "vmess";
|
||||
$aNode["tag"] = $aV2ray['country'] ?? '';
|
||||
$aNode["server"] = $aConfig["add"] ?? '';
|
||||
$aNode["server_port"] = $aConfig["port"] ?? ''; // Cannot access offset of type string on string
|
||||
$aNode["server_port"] = (int) $aNode["server_port"];
|
||||
$aNode["uuid"] = $aConfig["id"] ?? '';
|
||||
$aNode["security"] = $aConfig["scy"] ?? 'auto';
|
||||
$aNode["alter_id"] = $aConfig["aid"] ?? 0; // 猜的
|
||||
$aNode["alter_id"] = (int) $aNode["alter_id"];
|
||||
|
||||
// 1. 类型安全防御:确保 $aConfig 一定是数组
|
||||
$aConfig = $aV2ray['config'] ?? [];
|
||||
if (is_string($aConfig)) {
|
||||
$aConfig = json_decode($aConfig, true) ?? [];
|
||||
}
|
||||
if (!is_array($aConfig)) {
|
||||
$aConfig = [];
|
||||
}
|
||||
|
||||
// 2. 基础节点属性映射
|
||||
$aNode = [
|
||||
'type' => 'vmess',
|
||||
'tag' => (string) ($aV2ray['country'] ?? ''),
|
||||
'server' => (string) ($aConfig['add'] ?? ''),
|
||||
'server_port' => (int) ($aConfig['port'] ?? 0),
|
||||
'uuid' => (string) ($aConfig['id'] ?? ''),
|
||||
'security' => !empty($aConfig['scy']) ? (string) $aConfig['scy'] : 'auto',
|
||||
'alter_id' => (int) ($aConfig['aid'] ?? 0),
|
||||
];
|
||||
|
||||
// 3. 传输层 (Transport) 映射逻辑
|
||||
$sV2rayNet = strtolower((string) ($aConfig['net'] ?? 'tcp'));
|
||||
$sV2rayType = strtolower((string) ($aConfig['type'] ?? 'none'));
|
||||
$sRawPath = (string) ($aConfig['path'] ?? '');
|
||||
$sPath = !empty($sRawPath) ? rawurldecode($sRawPath) : '/';
|
||||
$sHost = (string) ($aConfig['host'] ?? '');
|
||||
|
||||
$aTransport = [];
|
||||
if (isset($aConfig["net"]) && $aConfig["net"] != "none" && $aConfig["net"] != "raw") {
|
||||
$aTransport["type"] = $aConfig["net"];
|
||||
|
||||
// 分支 A:TCP + HTTP 伪装
|
||||
if ($sV2rayNet === 'tcp' && $sV2rayType === 'http') {
|
||||
$aTransport['type'] = 'http';
|
||||
$aTransport['path'] = $sPath;
|
||||
if (!empty($sHost)) {
|
||||
$aTransport['host'] = array_map('trim', explode(',', $sHost));
|
||||
}
|
||||
}
|
||||
if (isset($aConfig["path"])) {
|
||||
$aTransport["path"] = rawurldecode($aConfig["path"]);
|
||||
// 分支 B:WebSocket 传输
|
||||
elseif ($sV2rayNet === 'ws') {
|
||||
$aTransport['type'] = 'ws';
|
||||
$aTransport['path'] = $sPath;
|
||||
if (!empty($sHost)) {
|
||||
$aTransport['headers'] = ['Host' => $sHost];
|
||||
}
|
||||
}
|
||||
if (isset($aConfig["host"])) {
|
||||
$aTransport["headers"]["Host"] = $aConfig["host"];
|
||||
// 分支 C:gRPC 传输
|
||||
elseif ($sV2rayNet === 'grpc') {
|
||||
$aTransport['type'] = 'grpc';
|
||||
$aTransport['service_name'] = $sRawPath;
|
||||
}
|
||||
// 分支 D:其他非 TCP 传输(如 mkcp, quic)
|
||||
elseif (!in_array($sV2rayNet, ['tcp', 'none', 'raw', ''], true)) {
|
||||
$aTransport['type'] = $sV2rayNet;
|
||||
}
|
||||
|
||||
if (!empty($aTransport)) {
|
||||
if (empty($aTransport["type"])) {
|
||||
$aTransport["type"] = "tcp";
|
||||
$aNode['transport'] = $aTransport;
|
||||
}
|
||||
|
||||
// 4. TLS 配置映射
|
||||
$sTlsType = strtolower((string) ($aConfig['tls'] ?? ''));
|
||||
if ($sTlsType === 'tls') {
|
||||
$sServerName = !empty($sHost) ? $sHost : $aNode['server'];
|
||||
|
||||
// 兼容类内 parseServerName 方法
|
||||
if (method_exists($this, 'parseServerName')) {
|
||||
$sServerName = $this->parseServerName($sServerName, $sServerName);
|
||||
}
|
||||
$aNode["transport"] = $aTransport;
|
||||
|
||||
$aNode['tls'] = [
|
||||
'enabled' => true,
|
||||
'server_name' => $sServerName,
|
||||
];
|
||||
}
|
||||
|
||||
$aTls = [];
|
||||
if (isset($aConfig["tls"])) {
|
||||
if ($aConfig["tls"] == "tls") {
|
||||
$aTls["server_name"] = !empty($aConfig['host']) ? $aConfig['host'] : $aConfig['add'];
|
||||
$aTls["server_name"] = $this->parseServerName($aTls["server_name"], $aTls["server_name"]);
|
||||
}
|
||||
}
|
||||
if (!empty($aTls)) {
|
||||
$aTls["enabled"] = true;
|
||||
$aNode["tls"] = $aTls;
|
||||
}
|
||||
|
||||
$aV2ray["config"] = $aNode;
|
||||
|
||||
|
||||
// 5. 替换配置并输出同等结构
|
||||
$aV2ray['config'] = $aNode;
|
||||
|
||||
return $aV2ray;
|
||||
}
|
||||
|
||||
// private function mod_to_vmess($aV2ray)
|
||||
// {
|
||||
// $aNode = [];
|
||||
// $aConfig = $aV2ray["config"];
|
||||
//
|
||||
// $aNode["type"] = "vmess";
|
||||
// $aNode["tag"] = $aV2ray['country'] ?? '';
|
||||
// $aNode["server"] = $aConfig["add"] ?? '';
|
||||
// $aNode["server_port"] = $aConfig["port"] ?? ''; // Cannot access offset of type string on string
|
||||
// $aNode["server_port"] = (int) $aNode["server_port"];
|
||||
// $aNode["uuid"] = $aConfig["id"] ?? '';
|
||||
// $aNode["security"] = $aConfig["scy"] ?? 'auto';
|
||||
// $aNode["alter_id"] = $aConfig["aid"] ?? 0; // 猜的
|
||||
// $aNode["alter_id"] = (int) $aNode["alter_id"];
|
||||
//
|
||||
// $aTransport = [];
|
||||
// if (isset($aConfig["net"]) && $aConfig["net"] != "none" && $aConfig["net"] != "raw") {
|
||||
// $aTransport["type"] = $aConfig["net"];
|
||||
// }
|
||||
// if (isset($aConfig["path"])) {
|
||||
// $aTransport["path"] = rawurldecode($aConfig["path"]);
|
||||
// }
|
||||
// if (isset($aConfig["host"])) {
|
||||
// $aTransport["headers"]["Host"] = $aConfig["host"];
|
||||
// }
|
||||
// if (!empty($aTransport)) {
|
||||
// if (empty($aTransport["type"])) {
|
||||
// $aTransport["type"] = "tcp";
|
||||
// }
|
||||
// $aNode["transport"] = $aTransport;
|
||||
// }
|
||||
//
|
||||
// $aTls = [];
|
||||
// if (isset($aConfig["tls"])) {
|
||||
// if ($aConfig["tls"] == "tls") {
|
||||
// $aTls["server_name"] = !empty($aConfig['host']) ? $aConfig['host'] : $aConfig['add'];
|
||||
// $aTls["server_name"] = $this->parseServerName($aTls["server_name"], $aTls["server_name"]);
|
||||
// }
|
||||
// }
|
||||
// if (!empty($aTls)) {
|
||||
// $aTls["enabled"] = true;
|
||||
// $aNode["tls"] = $aTls;
|
||||
// }
|
||||
//
|
||||
// $aV2ray["config"] = $aNode;
|
||||
//
|
||||
// return $aV2ray;
|
||||
// } // 这是原版代码,不行。你给我重写。传入和返回值一致即可
|
||||
|
||||
private function mod_to_vless__($aV2ray)
|
||||
{
|
||||
$sConfig = $aV2ray['config'] ?? '';
|
||||
|
||||
@ -4,7 +4,7 @@ namespace App\Services\Tg\Hook\Mod;
|
||||
|
||||
use App\Models\Blade as ModelBlade;
|
||||
use App\Services\Tg\Hook\Dog;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Blade extends Base {
|
||||
|
||||
|
||||
149
app/Services/Tg/Hook/Mod/FnLook.php
Executable file
149
app/Services/Tg/Hook/Mod/FnLook.php
Executable file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Tg\Hook\Mod;
|
||||
|
||||
use App\Models\FreenodePool;
|
||||
use App\Services\Tg\Hook\Dog;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FnLook extends Base {
|
||||
|
||||
private $oDog;
|
||||
|
||||
public function __construct($aUpdate)
|
||||
{
|
||||
|
||||
$this->oDog = new Dog(new FreenodePool());
|
||||
$this->oDog->_setDogName("fnLook"); // 必须,me用,正常就是类名,只不过后期没准改名,所以就这里写死
|
||||
// $this->oDog->_setPrimaryKey("code"); // 可选,默认id
|
||||
// $this->oDog->_setStrField(["content"]); // 可选,指定长文本字段
|
||||
|
||||
}
|
||||
|
||||
public function __call($sName, $aArg)
|
||||
{
|
||||
|
||||
return $this->oDog->$sName($aArg[0]);
|
||||
|
||||
}
|
||||
|
||||
// 筛选生成订阅,比如只生成vmess协议的
|
||||
// 暂时只支持v2ray
|
||||
public function tichun($aParam)
|
||||
{
|
||||
$sClient = $aParam["aOption"][1] ?? "v2ray";
|
||||
$sXieyi = $aParam["aOption"][2] ?? "all";
|
||||
$aLike = $aParam["aArg"] ?? [];
|
||||
$sLike = implode("", $aLike);
|
||||
|
||||
if ($sLike == "?") {
|
||||
return "#tichun__[client]__[xieyi,可用all]__[like,可空]";
|
||||
}
|
||||
|
||||
$sDate = date("Y-m-d");
|
||||
$sContent = FreenodePool::whereDate("date", $sDate)->first()?->content;
|
||||
$aContent = json_decode($sContent, true);
|
||||
|
||||
$cClientContent = $aContent[$sClient];
|
||||
|
||||
$cNode = [];
|
||||
$sMerge = '';
|
||||
if ($sClient == "v2ray") {
|
||||
|
||||
foreach ($cClientContent as $aClientContent) {
|
||||
$sContentXieyi = $aClientContent["protocolType"] ?? '';
|
||||
|
||||
if ($sXieyi != "all" && $sContentXieyi != $sXieyi) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sNodeName = $aClientContent["country"];
|
||||
|
||||
if ($sLike) {
|
||||
if (!Str::contains($sNodeName, $sLike, true)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$sConfig = $aClientContent["config"];
|
||||
|
||||
if (is_array($sConfig)) {
|
||||
$sConfig["ps"] = "xx".rand(1, 999);
|
||||
$sConfig = json_encode($sConfig);
|
||||
}
|
||||
|
||||
// $sNodeName = preg_replace('/ :\[.*?\]:/su', '', $sNodeName);
|
||||
//
|
||||
// tt($sNodeName);
|
||||
$sConfig = base64_encode($sConfig);
|
||||
$sNodeTmp = $sContentXieyi."://".$sConfig;
|
||||
$cNode[] = $sNodeTmp;
|
||||
}
|
||||
|
||||
// tt($cNode);
|
||||
$sMerge = implode("\n", $cNode);
|
||||
$sMerge = base64_encode($sMerge);
|
||||
|
||||
}
|
||||
|
||||
return $sMerge;
|
||||
// tt($sMerge);
|
||||
// exit;
|
||||
// tt($cClientContent);
|
||||
}
|
||||
|
||||
|
||||
// 比较节点数据。目前用于singbox比较原v2ray
|
||||
public function duibi($aParam)
|
||||
{
|
||||
$sClient = $aParam["aOption"][1] ?? "singbox";
|
||||
$sXieyi = $aParam["aOption"][2] ?? "all";
|
||||
$aLike = $aParam["aArg"] ?? [];
|
||||
$sLike = implode(" ", $aLike);
|
||||
|
||||
if ($sLike == "?") {
|
||||
return "#duibi__[client]__[xieyi,可用all]__[like,可空]";
|
||||
}
|
||||
|
||||
$sDate = date("Y-m-d");
|
||||
$sContent = FreenodePool::whereDate("date", $sDate)->first()?->content;
|
||||
$aContent = json_decode($sContent, true);
|
||||
|
||||
$cClientContent = $aContent[$sClient];
|
||||
|
||||
$sNode = "";
|
||||
|
||||
if ($sClient == "singbox") {
|
||||
foreach ($cClientContent as $sMd5 => $aClientContent) {
|
||||
|
||||
$sContentXieyi = $aClientContent["protocolType"] ?? '';
|
||||
|
||||
if ($sXieyi != "all" && $sContentXieyi != $sXieyi) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sNodeName = $aClientContent["country"];
|
||||
|
||||
if ($sLike) {
|
||||
if (!Str::contains($sNodeName, $sLike, true)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$sClientContent = json_encode($aClientContent, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$cV2rayContent = $aContent["v2ray"] ?? [];
|
||||
|
||||
$aV2rayContent = $cV2rayContent[$sMd5] ?? '';
|
||||
$sV2rayContent = json_encode($aV2rayContent, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$sNode .= "\n\n"."v2ray:\n".$sV2rayContent;
|
||||
$sNode .= "\n\n".$sClient.":\n".$sClientContent;
|
||||
$sNode .= "\n\n=========================================================================================";
|
||||
}
|
||||
}
|
||||
|
||||
return $sNode;
|
||||
}
|
||||
|
||||
}
|
||||
@ -50,6 +50,11 @@ use App\Http\Controllers\Web\Nasa\V1\ResourceArticleBaseController as NasaResour
|
||||
use App\Http\Controllers\Web\Nasa\V1\ResourceUploadimagesBaseController as NasaResourceUploadimagesBaseController;
|
||||
use App\Http\Controllers\Web\Nasa\V1\ActionsController as NasaActionsController;
|
||||
use App\Http\Controllers\Web\Nasa\V1\GithubArticleGithubController as NasaGithubArticleGithubController;
|
||||
use App\Http\Controllers\SakaiFnController;
|
||||
|
||||
Route::prefix('sakai')->group(function() {
|
||||
Route::get('fn/looktrans/{client}/{xieyi}/{like?}', [SakaiFnController::class, 'looktrans']); // like可以空怎么表示
|
||||
});
|
||||
|
||||
Route::get('/birds/create', [BirdController::class, 'create'])->name('birds.create'); // 录入界面
|
||||
Route::get('/birds/{id}', [BirdController::class, 'show'])->name('birds.show'); // 详情展示界面
|
||||
|
||||
Loading…
Reference in New Issue
Block a user