mirror of
https://github.com/v2board/v2board.git
synced 2025-01-11 08:39:09 +08:00
commit
b5376c9c1e
@ -117,7 +117,8 @@ class CheckOrder extends Command
|
|||||||
$user->expired_at = time();
|
$user->expired_at = time();
|
||||||
}
|
}
|
||||||
$user->transfer_enable = $plan->transfer_enable * 1073741824;
|
$user->transfer_enable = $plan->transfer_enable * 1073741824;
|
||||||
if ((int)config('v2board.renew_reset_traffic_enable', 1)) {
|
// 当续费清空流量或用户先前是一次性订阅
|
||||||
|
if ((int)config('v2board.renew_reset_traffic_enable', 1) || $user->expired_at === NULL) {
|
||||||
$user->u = 0;
|
$user->u = 0;
|
||||||
$user->d = 0;
|
$user->d = 0;
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Utils\CacheKey;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Order;
|
|
||||||
use App\Models\Server;
|
|
||||||
use App\Models\ServerLog;
|
use App\Models\ServerLog;
|
||||||
use App\Utils\Helper;
|
use App\Models\ServerStat;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class V2boardCache extends Command
|
class V2boardCache extends Command
|
||||||
{
|
{
|
||||||
@ -44,4 +43,26 @@ class V2boardCache extends Command
|
|||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function cacheServerStat()
|
||||||
|
{
|
||||||
|
$serverLogs = ServerLog::select(
|
||||||
|
'server_id',
|
||||||
|
DB::raw("sum(u) as u"),
|
||||||
|
DB::raw("sum(d) as d"),
|
||||||
|
DB::raw("count(*) as online")
|
||||||
|
)
|
||||||
|
->where('updated_at', '>=', time() - 3600)
|
||||||
|
->groupBy('server_id')
|
||||||
|
->get();
|
||||||
|
foreach ($serverLogs as $serverLog) {
|
||||||
|
$data = [
|
||||||
|
'server_id' => $serverLog->server_id,
|
||||||
|
'u' => $serverLog->u,
|
||||||
|
'd' => $serverLog->d,
|
||||||
|
'online' => $serverLog->online
|
||||||
|
];
|
||||||
|
// ServerStat::create($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ class V2boardInstall extends Command
|
|||||||
abort(500, '管理员密码长度最小为8位字符');
|
abort(500, '管理员密码长度最小为8位字符');
|
||||||
}
|
}
|
||||||
$user->password = password_hash($password, PASSWORD_DEFAULT);
|
$user->password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
$user->v2ray_uuid = Helper::guid(true);
|
$user->uuid = Helper::guid(true);
|
||||||
$user->token = Helper::guid();
|
$user->token = Helper::guid();
|
||||||
$user->is_admin = 1;
|
$user->is_admin = 1;
|
||||||
return $user->save();
|
return $user->save();
|
||||||
|
@ -76,6 +76,7 @@ class ConfigController extends Controller
|
|||||||
// stripe
|
// stripe
|
||||||
'stripe_alipay_enable' => (int)config('v2board.stripe_alipay_enable', 0),
|
'stripe_alipay_enable' => (int)config('v2board.stripe_alipay_enable', 0),
|
||||||
'stripe_wepay_enable' => (int)config('v2board.stripe_wepay_enable', 0),
|
'stripe_wepay_enable' => (int)config('v2board.stripe_wepay_enable', 0),
|
||||||
|
'stripe_card_enable' => (int)config('v2board.stripe_card_enable', 0),
|
||||||
'stripe_sk_live' => config('v2board.stripe_sk_live'),
|
'stripe_sk_live' => config('v2board.stripe_sk_live'),
|
||||||
'stripe_pk_live' => config('v2board.stripe_pk_live'),
|
'stripe_pk_live' => config('v2board.stripe_pk_live'),
|
||||||
'stripe_webhook_key' => config('v2board.stripe_webhook_key'),
|
'stripe_webhook_key' => config('v2board.stripe_webhook_key'),
|
||||||
|
@ -12,24 +12,25 @@ class CouponController extends Controller
|
|||||||
{
|
{
|
||||||
public function fetch(Request $request)
|
public function fetch(Request $request)
|
||||||
{
|
{
|
||||||
|
$coupons = Coupon::all();
|
||||||
|
foreach ($coupons as $k => $v) {
|
||||||
|
if ($coupons[$k]['limit_plan_ids']) $coupons[$k]['limit_plan_ids'] = json_decode($coupons[$k]['limit_plan_ids']);
|
||||||
|
}
|
||||||
return response([
|
return response([
|
||||||
'data' => Coupon::all()
|
'data' => $coupons
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(CouponSave $request)
|
public function save(CouponSave $request)
|
||||||
{
|
{
|
||||||
$params = $request->only([
|
$params = $request->only(array_keys(CouponSave::RULES));
|
||||||
'name',
|
if (isset($params['limit_plan_ids'])) {
|
||||||
'type',
|
$params['limit_plan_ids'] = json_encode($params['limit_plan_ids']);
|
||||||
'value',
|
}
|
||||||
'started_at',
|
|
||||||
'ended_at',
|
|
||||||
'limit_use'
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$request->input('id')) {
|
if (!$request->input('id')) {
|
||||||
|
if (!$params['code']) {
|
||||||
$params['code'] = Helper::randomChar(8);
|
$params['code'] = Helper::randomChar(8);
|
||||||
|
}
|
||||||
if (!Coupon::create($params)) {
|
if (!Coupon::create($params)) {
|
||||||
abort(500, '创建失败');
|
abort(500, '创建失败');
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,27 @@ class PlanController extends Controller
|
|||||||
{
|
{
|
||||||
public function fetch(Request $request)
|
public function fetch(Request $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$counts = User::select(
|
||||||
|
DB::raw("plan_id"),
|
||||||
|
DB::raw("count(*) as count")
|
||||||
|
)
|
||||||
|
->where('plan_id', '!=', NULL)
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->where('expired_at', '>=', time())
|
||||||
|
->orWhere('expired_at', NULL);
|
||||||
|
})
|
||||||
|
->groupBy("plan_id")
|
||||||
|
->get();
|
||||||
|
$plans = Plan::orderBy('sort', 'ASC')->get();
|
||||||
|
foreach ($plans as $k => $v) {
|
||||||
|
$plans[$k]->count = 0;
|
||||||
|
foreach ($counts as $kk => $vv) {
|
||||||
|
if ($plans[$k]->id === $counts[$kk]->plan_id) $plans[$k]->count = $counts[$kk]->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
return response([
|
return response([
|
||||||
'data' => Plan::orderBy('sort', 'ASC')->get()
|
'data' => $plans
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
app/Http/Controllers/Admin/Server/GroupController.php
Normal file
71
app/Http/Controllers/Admin/Server/GroupController.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin\Server;
|
||||||
|
|
||||||
|
use App\Models\Plan;
|
||||||
|
use App\Models\Server;
|
||||||
|
use App\Models\ServerGroup;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
|
class GroupController extends Controller
|
||||||
|
{
|
||||||
|
public function fetch(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->input('group_id')) {
|
||||||
|
return response([
|
||||||
|
'data' => [ServerGroup::find($request->input('group_id'))]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'data' => ServerGroup::get()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(Request $request)
|
||||||
|
{
|
||||||
|
if (empty($request->input('name'))) {
|
||||||
|
abort(500, '组名不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->input('id')) {
|
||||||
|
$serverGroup = ServerGroup::find($request->input('id'));
|
||||||
|
} else {
|
||||||
|
$serverGroup = new ServerGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
$serverGroup->name = $request->input('name');
|
||||||
|
return response([
|
||||||
|
'data' => $serverGroup->save()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function drop(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->input('id')) {
|
||||||
|
$serverGroup = ServerGroup::find($request->input('id'));
|
||||||
|
if (!$serverGroup) {
|
||||||
|
abort(500, '组不存在');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$servers = Server::all();
|
||||||
|
foreach ($servers as $server) {
|
||||||
|
$groupId = json_decode($server->group_id);
|
||||||
|
if (in_array($request->input('id'), $groupId)) {
|
||||||
|
abort(500, '该组已被节点所使用,无法删除');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Plan::where('group_id', $request->input('id'))->first()) {
|
||||||
|
abort(500, '该组已被订阅所使用,无法删除');
|
||||||
|
}
|
||||||
|
if (User::where('group_id', $request->input('id'))->first()) {
|
||||||
|
abort(500, '该组已被用户所使用,无法删除');
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'data' => $serverGroup->delete()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
144
app/Http/Controllers/Admin/Server/TrojanController.php
Normal file
144
app/Http/Controllers/Admin/Server/TrojanController.php
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin\Server;
|
||||||
|
|
||||||
|
use App\Http\Requests\Admin\ServerTrojanSave;
|
||||||
|
use App\Http\Requests\Admin\ServerTrojanSort;
|
||||||
|
use App\Http\Requests\Admin\ServerTrojanUpdate;
|
||||||
|
use App\Services\ServerService;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ServerTrojan;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class TrojanController extends Controller
|
||||||
|
{
|
||||||
|
public function fetch(Request $request)
|
||||||
|
{
|
||||||
|
$server = ServerTrojan::orderBy('sort', 'ASC')->get();
|
||||||
|
for ($i = 0; $i < count($server); $i++) {
|
||||||
|
if (!empty($server[$i]['tags'])) {
|
||||||
|
$server[$i]['tags'] = json_decode($server[$i]['tags']);
|
||||||
|
}
|
||||||
|
$server[$i]['group_id'] = json_decode($server[$i]['group_id']);
|
||||||
|
$server[$i]['online'] = Cache::get(CacheKey::get('SERVER_TROJAN_ONLINE_USER', $server[$i]['id']));
|
||||||
|
if ($server[$i]['parent_id']) {
|
||||||
|
$server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server[$i]['parent_id']));
|
||||||
|
} else {
|
||||||
|
$server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server[$i]['id']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'data' => $server
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(ServerTrojanSave $request)
|
||||||
|
{
|
||||||
|
$params = $request->only(array_keys(ServerTrojanSave::RULES));
|
||||||
|
$params['group_id'] = json_encode($params['group_id']);
|
||||||
|
if (isset($params['tags'])) {
|
||||||
|
$params['tags'] = json_encode($params['tags']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->input('id')) {
|
||||||
|
$server = ServerTrojan::find($request->input('id'));
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '服务器不存在');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$server->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
abort(500, '保存失败');
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ServerTrojan::create($params)) {
|
||||||
|
abort(500, '创建失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function drop(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->input('id')) {
|
||||||
|
$server = ServerTrojan::find($request->input('id'));
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '节点ID不存在');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'data' => $server->delete()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(ServerTrojanUpdate $request)
|
||||||
|
{
|
||||||
|
$params = $request->only([
|
||||||
|
'show',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$server = ServerTrojan::find($request->input('id'));
|
||||||
|
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '该服务器不存在');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$server->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
abort(500, '保存失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function copy(Request $request)
|
||||||
|
{
|
||||||
|
$server = ServerTrojan::find($request->input('id'));
|
||||||
|
$server->show = 0;
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '服务器不存在');
|
||||||
|
}
|
||||||
|
if (!ServerTrojan::create($server->toArray())) {
|
||||||
|
abort(500, '复制失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sort(ServerTrojanSort $request)
|
||||||
|
{
|
||||||
|
DB::beginTransaction();
|
||||||
|
foreach ($request->input('server_ids') as $k => $v) {
|
||||||
|
if (!ServerTrojan::find($v)->update(['sort' => $k + 1])) {
|
||||||
|
DB::rollBack();
|
||||||
|
abort(500, '保存失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DB::commit();
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewConfig(Request $request)
|
||||||
|
{
|
||||||
|
$serverService = new ServerService();
|
||||||
|
$config = $serverService->getTrojanConfig($request->input('node_id'), 23333);
|
||||||
|
return response([
|
||||||
|
'data' => $config
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
88
app/Http/Controllers/Admin/ServerController.php → app/Http/Controllers/Admin/Server/V2rayController.php
Executable file → Normal file
88
app/Http/Controllers/Admin/ServerController.php → app/Http/Controllers/Admin/Server/V2rayController.php
Executable file → Normal file
@ -1,21 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin\Server;
|
||||||
|
|
||||||
use App\Http\Requests\Admin\ServerSave;
|
use App\Http\Requests\Admin\ServerV2raySave;
|
||||||
use App\Http\Requests\Admin\ServerSort;
|
use App\Http\Requests\Admin\ServerV2raySort;
|
||||||
use App\Http\Requests\Admin\ServerUpdate;
|
use App\Http\Requests\Admin\ServerV2rayUpdate;
|
||||||
use App\Services\ServerService;
|
use App\Services\ServerService;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\ServerGroup;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Plan;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class ServerController extends Controller
|
class V2rayController extends Controller
|
||||||
{
|
{
|
||||||
public function fetch(Request $request)
|
public function fetch(Request $request)
|
||||||
{
|
{
|
||||||
@ -25,10 +23,11 @@ class ServerController extends Controller
|
|||||||
$server[$i]['tags'] = json_decode($server[$i]['tags']);
|
$server[$i]['tags'] = json_decode($server[$i]['tags']);
|
||||||
}
|
}
|
||||||
$server[$i]['group_id'] = json_decode($server[$i]['group_id']);
|
$server[$i]['group_id'] = json_decode($server[$i]['group_id']);
|
||||||
|
$server[$i]['online'] = Cache::get(CacheKey::get('SERVER_V2RAY_ONLINE_USER', $server[$i]['parent_id'] ? $server[$i]['parent_id'] : $server[$i]['id']));
|
||||||
if ($server[$i]['parent_id']) {
|
if ($server[$i]['parent_id']) {
|
||||||
$server[$i]['last_check_at'] = Cache::get('server_last_check_at_' . $server[$i]['parent_id']);
|
$server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $server[$i]['parent_id']));
|
||||||
} else {
|
} else {
|
||||||
$server[$i]['last_check_at'] = Cache::get('server_last_check_at_' . $server[$i]['id']);
|
$server[$i]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $server[$i]['id']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response([
|
return response([
|
||||||
@ -36,9 +35,9 @@ class ServerController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(ServerSave $request)
|
public function save(ServerV2raySave $request)
|
||||||
{
|
{
|
||||||
$params = $request->only(array_keys(ServerSave::RULES));
|
$params = $request->only(array_keys(ServerV2raySave::RULES));
|
||||||
$params['group_id'] = json_encode($params['group_id']);
|
$params['group_id'] = json_encode($params['group_id']);
|
||||||
if (isset($params['tags'])) {
|
if (isset($params['tags'])) {
|
||||||
$params['tags'] = json_encode($params['tags']);
|
$params['tags'] = json_encode($params['tags']);
|
||||||
@ -92,64 +91,6 @@ class ServerController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function groupFetch(Request $request)
|
|
||||||
{
|
|
||||||
if ($request->input('group_id')) {
|
|
||||||
return response([
|
|
||||||
'data' => [ServerGroup::find($request->input('group_id'))]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
return response([
|
|
||||||
'data' => ServerGroup::get()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function groupSave(Request $request)
|
|
||||||
{
|
|
||||||
if (empty($request->input('name'))) {
|
|
||||||
abort(500, '组名不能为空');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->input('id')) {
|
|
||||||
$serverGroup = ServerGroup::find($request->input('id'));
|
|
||||||
} else {
|
|
||||||
$serverGroup = new ServerGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
$serverGroup->name = $request->input('name');
|
|
||||||
return response([
|
|
||||||
'data' => $serverGroup->save()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function groupDrop(Request $request)
|
|
||||||
{
|
|
||||||
if ($request->input('id')) {
|
|
||||||
$serverGroup = ServerGroup::find($request->input('id'));
|
|
||||||
if (!$serverGroup) {
|
|
||||||
abort(500, '组不存在');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$servers = Server::all();
|
|
||||||
foreach ($servers as $server) {
|
|
||||||
$groupId = json_decode($server->group_id);
|
|
||||||
if (in_array($request->input('id'), $groupId)) {
|
|
||||||
abort(500, '该组已被节点所使用,无法删除');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Plan::where('group_id', $request->input('id'))->first()) {
|
|
||||||
abort(500, '该组已被订阅所使用,无法删除');
|
|
||||||
}
|
|
||||||
if (User::where('group_id', $request->input('id'))->first()) {
|
|
||||||
abort(500, '该组已被用户所使用,无法删除');
|
|
||||||
}
|
|
||||||
return response([
|
|
||||||
'data' => $serverGroup->delete()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function drop(Request $request)
|
public function drop(Request $request)
|
||||||
{
|
{
|
||||||
if ($request->input('id')) {
|
if ($request->input('id')) {
|
||||||
@ -163,7 +104,7 @@ class ServerController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(ServerUpdate $request)
|
public function update(ServerV2rayUpdate $request)
|
||||||
{
|
{
|
||||||
$params = $request->only([
|
$params = $request->only([
|
||||||
'show',
|
'show',
|
||||||
@ -188,6 +129,7 @@ class ServerController extends Controller
|
|||||||
public function copy(Request $request)
|
public function copy(Request $request)
|
||||||
{
|
{
|
||||||
$server = Server::find($request->input('id'));
|
$server = Server::find($request->input('id'));
|
||||||
|
$server->show = 0;
|
||||||
if (!$server) {
|
if (!$server) {
|
||||||
abort(500, '服务器不存在');
|
abort(500, '服务器不存在');
|
||||||
}
|
}
|
||||||
@ -203,13 +145,13 @@ class ServerController extends Controller
|
|||||||
public function viewConfig(Request $request)
|
public function viewConfig(Request $request)
|
||||||
{
|
{
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
$config = $serverService->getConfig($request->input('node_id'), 23333);
|
$config = $serverService->getVmessConfig($request->input('node_id'), 23333);
|
||||||
return response([
|
return response([
|
||||||
'data' => $config
|
'data' => $config
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sort(ServerSort $request)
|
public function sort(ServerV2raySort $request)
|
||||||
{
|
{
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
foreach ($request->input('server_ids') as $k => $v) {
|
foreach ($request->input('server_ids') as $k => $v) {
|
@ -3,12 +3,12 @@
|
|||||||
namespace App\Http\Controllers\Client;
|
namespace App\Http\Controllers\Client;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Services\ServerService;
|
||||||
|
use App\Services\UserService;
|
||||||
|
use App\Utils\Clash;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Plan;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Notice;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
use App\Utils\Helper;
|
|
||||||
|
|
||||||
class AppController extends Controller
|
class AppController extends Controller
|
||||||
{
|
{
|
||||||
@ -16,38 +16,40 @@ class AppController extends Controller
|
|||||||
CONST SOCKS_PORT = 10010;
|
CONST SOCKS_PORT = 10010;
|
||||||
CONST HTTP_PORT = 10011;
|
CONST HTTP_PORT = 10011;
|
||||||
|
|
||||||
// TODO: 1.1.1 abolish
|
public function getConfig(Request $request)
|
||||||
public function data(Request $request)
|
|
||||||
{
|
{
|
||||||
|
$server = [];
|
||||||
$user = $request->user;
|
$user = $request->user;
|
||||||
$nodes = [];
|
$userService = new UserService();
|
||||||
if ($user->plan_id) {
|
if ($userService->isAvailable($user)) {
|
||||||
$user['plan'] = Plan::find($user->plan_id);
|
$serverService = new ServerService();
|
||||||
if (!$user['plan']) {
|
$servers = $serverService->getAllServers($user);
|
||||||
abort(500, '订阅计划不存在');
|
|
||||||
}
|
}
|
||||||
if ($user->expired_at > time()) {
|
$config = Yaml::parseFile(base_path() . '/resources/rules/app.clash.yaml');
|
||||||
$servers = Server::where('show', 1)
|
$proxy = [];
|
||||||
->orderBy('name')
|
$proxies = [];
|
||||||
->get();
|
|
||||||
foreach ($servers as $item) {
|
foreach ($servers['vmess'] as $item) {
|
||||||
$groupId = json_decode($item['group_id']);
|
array_push($proxy, Clash::buildVmess($user->uuid, $item));
|
||||||
if (in_array($user->group_id, $groupId)) {
|
array_push($proxies, $item->name);
|
||||||
array_push($nodes, $item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($servers['trojan'] as $item) {
|
||||||
|
array_push($proxy, Clash::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) {
|
||||||
|
$config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxies);
|
||||||
}
|
}
|
||||||
|
die(Yaml::dump($config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getVersion()
|
||||||
|
{
|
||||||
return response([
|
return response([
|
||||||
'data' => [
|
'data' => '4.0.0'
|
||||||
'nodes' => $nodes,
|
|
||||||
'u' => $user->u,
|
|
||||||
'd' => $user->d,
|
|
||||||
'transfer_enable' => $user->transfer_enable,
|
|
||||||
'expired_at' => $user->expired_at,
|
|
||||||
'plan' => isset($user['plan']) ? $user['plan'] : false,
|
|
||||||
'notice' => Notice::orderBy('created_at', 'DESC')->first()
|
|
||||||
]
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ class AppController extends Controller
|
|||||||
//other
|
//other
|
||||||
$json->outbound->settings->vnext[0]->address = (string)$server->host;
|
$json->outbound->settings->vnext[0]->address = (string)$server->host;
|
||||||
$json->outbound->settings->vnext[0]->port = (int)$server->port;
|
$json->outbound->settings->vnext[0]->port = (int)$server->port;
|
||||||
$json->outbound->settings->vnext[0]->users[0]->id = (string)$user->v2ray_uuid;
|
$json->outbound->settings->vnext[0]->users[0]->id = (string)$user->uuid;
|
||||||
$json->outbound->settings->vnext[0]->users[0]->alterId = (int)$user->v2ray_alter_id;
|
$json->outbound->settings->vnext[0]->users[0]->alterId = (int)$user->v2ray_alter_id;
|
||||||
$json->outbound->settings->vnext[0]->remark = (string)$server->name;
|
$json->outbound->settings->vnext[0]->remark = (string)$server->name;
|
||||||
$json->outbound->streamSettings->network = $server->network;
|
$json->outbound->streamSettings->network = $server->network;
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
namespace App\Http\Controllers\Client;
|
namespace App\Http\Controllers\Client;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Services\ServerService;
|
||||||
|
use App\Utils\Clash;
|
||||||
|
use App\Utils\QuantumultX;
|
||||||
|
use App\Utils\Surge;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Utils\Helper;
|
use App\Utils\Helper;
|
||||||
@ -14,76 +18,41 @@ class ClientController extends Controller
|
|||||||
public function subscribe(Request $request)
|
public function subscribe(Request $request)
|
||||||
{
|
{
|
||||||
$user = $request->user;
|
$user = $request->user;
|
||||||
$server = [];
|
|
||||||
// account not expired and is not banned.
|
// account not expired and is not banned.
|
||||||
$userService = new UserService();
|
$userService = new UserService();
|
||||||
if ($userService->isAvailable($user)) {
|
if ($userService->isAvailable($user)) {
|
||||||
$servers = Server::where('show', 1)
|
$serverService = new ServerService();
|
||||||
->orderBy('sort', 'ASC')
|
$servers = $serverService->getAllServers($user);
|
||||||
->get();
|
|
||||||
foreach ($servers as $item) {
|
|
||||||
$groupId = json_decode($item['group_id']);
|
|
||||||
if (in_array($user->group_id, $groupId)) {
|
|
||||||
array_push($server, $item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Quantumult%20X') !== false) {
|
$_SERVER['HTTP_USER_AGENT'] = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||||
die($this->quantumultX($user, $server));
|
if (strpos($_SERVER['HTTP_USER_AGENT'], 'quantumult%20x') !== false) {
|
||||||
|
die($this->quantumultX($user, $servers['vmess'], $servers['trojan']));
|
||||||
}
|
}
|
||||||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Quantumult') !== false) {
|
if (strpos($_SERVER['HTTP_USER_AGENT'], 'quantumult') !== false) {
|
||||||
die($this->quantumult($user, $server));
|
die($this->quantumult($user, $servers['vmess']));
|
||||||
}
|
}
|
||||||
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'clash') !== false) {
|
if (strpos($_SERVER['HTTP_USER_AGENT'], 'clash') !== false) {
|
||||||
die($this->clash($user, $server));
|
die($this->clash($user, $servers['vmess'], $servers['trojan']));
|
||||||
}
|
}
|
||||||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Surfboard') !== false) {
|
if (strpos($_SERVER['HTTP_USER_AGENT'], 'surfboard') !== false) {
|
||||||
die($this->surfboard($user, $server));
|
die($this->surfboard($user, $servers['vmess']));
|
||||||
}
|
}
|
||||||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Surge') !== false) {
|
if (strpos($_SERVER['HTTP_USER_AGENT'], 'surge') !== false) {
|
||||||
die($this->surge($user, $server));
|
die($this->surge($user, $servers['vmess'], $servers['trojan']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
die($this->origin($user, $server));
|
die($this->origin($user, $servers['vmess'], $servers['trojan']));
|
||||||
}
|
|
||||||
|
|
||||||
private function quantumultX($user, $server)
|
|
||||||
{
|
|
||||||
$uri = '';
|
|
||||||
foreach ($server as $item) {
|
|
||||||
$uri .= "vmess=" . $item->host . ":" . $item->port . ", method=none, password=" . $user->v2ray_uuid . ", fast-open=false, udp-relay=false, tag=" . $item->name;
|
|
||||||
if ($item->tls) {
|
|
||||||
$tlsSettings = json_decode($item->tlsSettings);
|
|
||||||
if ($item->network === 'tcp') $uri .= ', obfs=over-tls';
|
|
||||||
if (isset($tlsSettings->allowInsecure)) {
|
|
||||||
// Default: tls-verification=true
|
|
||||||
$uri .= ', tls-verification=' . ($tlsSettings->allowInsecure ? "false" : "true");
|
|
||||||
}
|
|
||||||
if (isset($tlsSettings->serverName)) {
|
|
||||||
$uri .= ', obfs-host=' . $tlsSettings->serverName;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($item->network === 'ws') {
|
// TODO: Ready to stop support
|
||||||
$uri .= ', obfs=' . ($item->tls ? 'wss' : 'ws');
|
private function quantumult($user, $vmess = [])
|
||||||
if ($item->networkSettings) {
|
|
||||||
$wsSettings = json_decode($item->networkSettings);
|
|
||||||
if (isset($wsSettings->path)) $uri .= ', obfs-uri=' . $wsSettings->path;
|
|
||||||
if (isset($wsSettings->headers->Host)) $uri .= ', obfs-host=' . $wsSettings->headers->Host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$uri .= "\r\n";
|
|
||||||
}
|
|
||||||
return base64_encode($uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function quantumult($user, $server)
|
|
||||||
{
|
{
|
||||||
$uri = '';
|
$uri = '';
|
||||||
header('subscription-userinfo: upload=' . $user->u . '; download=' . $user->d . ';total=' . $user->transfer_enable);
|
header('subscription-userinfo: upload=' . $user->u . '; download=' . $user->d . ';total=' . $user->transfer_enable);
|
||||||
foreach ($server as $item) {
|
foreach ($vmess as $item) {
|
||||||
$str = '';
|
$str = '';
|
||||||
$str .= $item->name . '= vmess, ' . $item->host . ', ' . $item->port . ', chacha20-ietf-poly1305, "' . $user->v2ray_uuid . '", over-tls=' . ($item->tls ? "true" : "false") . ', certificate=0, group=' . config('v2board.app_name', 'V2Board');
|
$str .= $item->name . '= vmess, ' . $item->host . ', ' . $item->port . ', chacha20-ietf-poly1305, "' . $user->uuid . '", over-tls=' . ($item->tls ? "true" : "false") . ', certificate=0, group=' . config('v2board.app_name', 'V2Board');
|
||||||
if ($item->network === 'ws') {
|
if ($item->network === 'ws') {
|
||||||
$str .= ', obfs=ws';
|
$str .= ', obfs=ws';
|
||||||
if ($item->networkSettings) {
|
if ($item->networkSettings) {
|
||||||
@ -97,38 +66,44 @@ class ClientController extends Controller
|
|||||||
return base64_encode($uri);
|
return base64_encode($uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function origin($user, $server)
|
private function quantumultX($user, $vmess = [], $trojan = [])
|
||||||
{
|
{
|
||||||
$uri = '';
|
$uri = '';
|
||||||
foreach ($server as $item) {
|
foreach ($vmess as $item) {
|
||||||
$uri .= Helper::buildVmessLink($item, $user);
|
$uri .= QuantumultX::buildVmess($user->uuid, $item);
|
||||||
|
}
|
||||||
|
foreach ($trojan as $item) {
|
||||||
|
$uri .= QuantumultX::buildTrojan($user->uuid, $item);
|
||||||
}
|
}
|
||||||
return base64_encode($uri);
|
return base64_encode($uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function surge($user, $server)
|
private function origin($user, $vmess = [], $trojan = [])
|
||||||
|
{
|
||||||
|
$uri = '';
|
||||||
|
foreach ($vmess as $item) {
|
||||||
|
$uri .= Helper::buildVmessLink($item, $user);
|
||||||
|
}
|
||||||
|
foreach ($trojan as $item) {
|
||||||
|
$uri .= Helper::buildTrojanLink($item, $user);
|
||||||
|
}
|
||||||
|
return base64_encode($uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function surge($user, $vmess = [], $trojan = [])
|
||||||
{
|
{
|
||||||
$proxies = '';
|
$proxies = '';
|
||||||
$proxyGroup = '';
|
$proxyGroup = '';
|
||||||
foreach ($server as $item) {
|
foreach ($vmess as $item) {
|
||||||
// [Proxy]
|
// [Proxy]
|
||||||
$proxies .= $item->name . ' = vmess, ' . $item->host . ', ' . $item->port . ', username=' . $user->v2ray_uuid . ', tfo=true';
|
$proxies .= Surge::buildVmess($user->uuid, $item);
|
||||||
if ($item->tls) {
|
// [Proxy Group]
|
||||||
$tlsSettings = json_decode($item->tlsSettings);
|
$proxyGroup .= $item->name . ', ';
|
||||||
$proxies .= ', tls=' . ($item->tls ? "true" : "false");
|
|
||||||
if (isset($tlsSettings->allowInsecure)) {
|
|
||||||
$proxies .= ', skip-cert-verify=' . ($tlsSettings->allowInsecure ? "true" : "false");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ($item->network == 'ws') {
|
foreach ($trojan as $item) {
|
||||||
$proxies .= ', ws=true';
|
// [Proxy]
|
||||||
if ($item->networkSettings) {
|
$proxies .= Surge::buildTrojan($user->uuid, $item);
|
||||||
$wsSettings = json_decode($item->networkSettings);
|
|
||||||
if (isset($wsSettings->path)) $proxies .= ', ws-path=' . $wsSettings->path;
|
|
||||||
if (isset($wsSettings->headers->Host)) $proxies .= ', ws-headers=host:' . $wsSettings->headers->Host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$proxies .= "\r\n";
|
|
||||||
// [Proxy Group]
|
// [Proxy Group]
|
||||||
$proxyGroup .= $item->name . ', ';
|
$proxyGroup .= $item->name . ', ';
|
||||||
}
|
}
|
||||||
@ -142,16 +117,7 @@ class ClientController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Subscription link
|
// Subscription link
|
||||||
$subsURL = 'http';
|
$subsURL = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token'];
|
||||||
if (isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on') {
|
|
||||||
$subsURL .= 's';
|
|
||||||
}
|
|
||||||
$subsURL .= '://';
|
|
||||||
if ($_SERVER['SERVER_PORT'] != ('80' || '443')) {
|
|
||||||
$subsURL .= $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
|
|
||||||
} else {
|
|
||||||
$subsURL .= $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$config = str_replace('$subs_link', $subsURL, $config);
|
$config = str_replace('$subs_link', $subsURL, $config);
|
||||||
$config = str_replace('$proxies', $proxies, $config);
|
$config = str_replace('$proxies', $proxies, $config);
|
||||||
@ -159,13 +125,13 @@ class ClientController extends Controller
|
|||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function surfboard($user, $server)
|
private function surfboard($user, $vmess = [])
|
||||||
{
|
{
|
||||||
$proxies = '';
|
$proxies = '';
|
||||||
$proxyGroup = '';
|
$proxyGroup = '';
|
||||||
foreach ($server as $item) {
|
foreach ($vmess as $item) {
|
||||||
// [Proxy]
|
// [Proxy]
|
||||||
$proxies .= $item->name . ' = vmess, ' . $item->host . ', ' . $item->port . ', username=' . $user->v2ray_uuid;
|
$proxies .= $item->name . ' = vmess, ' . $item->host . ', ' . $item->port . ', username=' . $user->uuid;
|
||||||
if ($item->tls) {
|
if ($item->tls) {
|
||||||
$tlsSettings = json_decode($item->tlsSettings);
|
$tlsSettings = json_decode($item->tlsSettings);
|
||||||
$proxies .= ', tls=' . ($item->tls ? "true" : "false");
|
$proxies .= ', tls=' . ($item->tls ? "true" : "false");
|
||||||
@ -195,16 +161,7 @@ class ClientController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Subscription link
|
// Subscription link
|
||||||
$subsURL = 'http';
|
$subsURL = config('v2board.subscribe_url', config('v2board.app_url', env('APP_URL'))) . '/api/v1/client/subscribe?token=' . $user['token'];
|
||||||
if (isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on') {
|
|
||||||
$subsURL .= 's';
|
|
||||||
}
|
|
||||||
$subsURL .= '://';
|
|
||||||
if ($_SERVER['SERVER_PORT'] != ('80' || '443')) {
|
|
||||||
$subsURL .= $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
|
|
||||||
} else {
|
|
||||||
$subsURL .= $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$config = str_replace('$subs_link', $subsURL, $config);
|
$config = str_replace('$subs_link', $subsURL, $config);
|
||||||
$config = str_replace('$proxies', $proxies, $config);
|
$config = str_replace('$proxies', $proxies, $config);
|
||||||
@ -212,7 +169,7 @@ class ClientController extends Controller
|
|||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function clash($user, $server)
|
private function clash($user, $vmess = [], $trojan = [])
|
||||||
{
|
{
|
||||||
$defaultConfig = base_path() . '/resources/rules/default.clash.yaml';
|
$defaultConfig = base_path() . '/resources/rules/default.clash.yaml';
|
||||||
$customConfig = base_path() . '/resources/rules/custom.clash.yaml';
|
$customConfig = base_path() . '/resources/rules/custom.clash.yaml';
|
||||||
@ -223,37 +180,20 @@ class ClientController extends Controller
|
|||||||
}
|
}
|
||||||
$proxy = [];
|
$proxy = [];
|
||||||
$proxies = [];
|
$proxies = [];
|
||||||
foreach ($server as $item) {
|
foreach ($vmess as $item) {
|
||||||
$array = [];
|
array_push($proxy, Clash::buildVmess($user->uuid, $item));
|
||||||
$array['name'] = $item->name;
|
|
||||||
$array['type'] = 'vmess';
|
|
||||||
$array['server'] = $item->host;
|
|
||||||
$array['port'] = $item->port;
|
|
||||||
$array['uuid'] = $user->v2ray_uuid;
|
|
||||||
$array['alterId'] = $user->v2ray_alter_id;
|
|
||||||
$array['cipher'] = 'auto';
|
|
||||||
if ($item->tls) {
|
|
||||||
$tlsSettings = json_decode($item->tlsSettings);
|
|
||||||
$array['tls'] = true;
|
|
||||||
if (isset($tlsSettings->allowInsecure)) $array['skip-cert-verify'] = ($tlsSettings->allowInsecure ? true : false );
|
|
||||||
}
|
|
||||||
if ($item->network == 'ws') {
|
|
||||||
$array['network'] = $item->network;
|
|
||||||
if ($item->networkSettings) {
|
|
||||||
$wsSettings = json_decode($item->networkSettings);
|
|
||||||
if (isset($wsSettings->path)) $array['ws-path'] = $wsSettings->path;
|
|
||||||
if (isset($wsSettings->headers->Host)) $array['ws-headers'] = [
|
|
||||||
'Host' => $wsSettings->headers->Host
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
array_push($proxy, $array);
|
|
||||||
array_push($proxies, $item->name);
|
array_push($proxies, $item->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
$config['Proxy'] = array_merge($config['Proxy'] ? $config['Proxy'] : [], $proxy);
|
|
||||||
foreach ($config['Proxy Group'] as $k => $v) {
|
foreach ($trojan as $item) {
|
||||||
$config['Proxy Group'][$k]['proxies'] = array_merge($config['Proxy Group'][$k]['proxies'], $proxies);
|
array_push($proxy, Clash::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) {
|
||||||
|
$config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxies);
|
||||||
}
|
}
|
||||||
$yaml = Yaml::dump($config);
|
$yaml = Yaml::dump($config);
|
||||||
$yaml = str_replace('$app_name', config('v2board.app_name', 'V2Board'), $yaml);
|
$yaml = str_replace('$app_name', config('v2board.app_name', 'V2Board'), $yaml);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Guest;
|
namespace App\Http\Controllers\Guest;
|
||||||
|
|
||||||
|
use App\Services\OrderService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
@ -66,22 +67,26 @@ class OrderController extends Controller
|
|||||||
}
|
}
|
||||||
switch ($event->type) {
|
switch ($event->type) {
|
||||||
case 'source.chargeable':
|
case 'source.chargeable':
|
||||||
$source = $event->data->object;
|
$object = $event->data->object;
|
||||||
$charge = \Stripe\Charge::create([
|
\Stripe\Charge::create([
|
||||||
'amount' => $source['amount'],
|
'amount' => $object->amount,
|
||||||
'currency' => $source['currency'],
|
'currency' => $object->currency,
|
||||||
'source' => $source['id'],
|
'source' => $object->id,
|
||||||
'description' => config('v2board.app_name', 'V2Board') . $source['metadata']['invoice_id'],
|
'metadata' => json_decode($object->metadata, true)
|
||||||
]);
|
]);
|
||||||
if ($charge['status'] == 'succeeded') {
|
die('success');
|
||||||
$trade_no = Cache::get($source['id']);
|
break;
|
||||||
if (!$trade_no) {
|
case 'charge.succeeded':
|
||||||
abort(500, 'redis is not found trade no by stripe source id');
|
$object = $event->data->object;
|
||||||
|
if ($object->status === 'succeeded') {
|
||||||
|
$metaData = isset($object->metadata->out_trade_no) ? $object->metadata : $object->source->metadata;
|
||||||
|
$tradeNo = $metaData->out_trade_no;
|
||||||
|
if (!$tradeNo) {
|
||||||
|
abort(500, 'trade no is not found in metadata');
|
||||||
}
|
}
|
||||||
if (!$this->handle($trade_no, $source['id'])) {
|
if (!$this->handle($tradeNo, $object->balance_transaction)) {
|
||||||
abort(500, 'fail');
|
abort(500, 'fail');
|
||||||
}
|
}
|
||||||
Cache::forget($source['id']);
|
|
||||||
die('success');
|
die('success');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -143,11 +148,7 @@ class OrderController extends Controller
|
|||||||
if (!$order) {
|
if (!$order) {
|
||||||
abort(500, 'order is not found');
|
abort(500, 'order is not found');
|
||||||
}
|
}
|
||||||
if ($order->status !== 0) {
|
$orderService = new OrderService($order);
|
||||||
return true;
|
return $orderService->success($callbackNo);
|
||||||
}
|
|
||||||
$order->status = 1;
|
|
||||||
$order->callback_no = $callbackNo;
|
|
||||||
return $order->save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ class TelegramController extends Controller
|
|||||||
break;
|
break;
|
||||||
case '/traffic': $this->traffic();
|
case '/traffic': $this->traffic();
|
||||||
break;
|
break;
|
||||||
|
case '/getlatesturl': $this->getLatestUrl();
|
||||||
|
break;
|
||||||
default: $this->help();
|
default: $this->help();
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@ -84,7 +86,8 @@ class TelegramController extends Controller
|
|||||||
$telegramService = new TelegramService();
|
$telegramService = new TelegramService();
|
||||||
$commands = [
|
$commands = [
|
||||||
'/bind 订阅地址 - 绑定你的' . config('v2board.app_name', 'V2Board') . '账号',
|
'/bind 订阅地址 - 绑定你的' . config('v2board.app_name', 'V2Board') . '账号',
|
||||||
'/traffic - 查询流量信息'
|
'/traffic - 查询流量信息',
|
||||||
|
'/getlatesturl - 获取最新的' . config('v2board.app_name', 'V2Board') . '网址'
|
||||||
];
|
];
|
||||||
$text = implode(PHP_EOL, $commands);
|
$text = implode(PHP_EOL, $commands);
|
||||||
$telegramService->sendMessage($msg->chat_id, "你可以使用以下命令进行操作:\n\n$text", 'markdown');
|
$telegramService->sendMessage($msg->chat_id, "你可以使用以下命令进行操作:\n\n$text", 'markdown');
|
||||||
@ -108,4 +111,17 @@ class TelegramController extends Controller
|
|||||||
$text = "🚥流量查询\n———————————————\n计划流量:`{$transferEnable}`\n已用上行:`{$up}`\n已用下行:`{$down}`\n剩余流量:`{$remaining}`";
|
$text = "🚥流量查询\n———————————————\n计划流量:`{$transferEnable}`\n已用上行:`{$up}`\n已用下行:`{$down}`\n剩余流量:`{$remaining}`";
|
||||||
$telegramService->sendMessage($msg->chat_id, $text, 'markdown');
|
$telegramService->sendMessage($msg->chat_id, $text, 'markdown');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getLatestUrl()
|
||||||
|
{
|
||||||
|
$msg = $this->msg;
|
||||||
|
$user = User::where('telegram_id', $msg->chat_id)->first();
|
||||||
|
$telegramService = new TelegramService();
|
||||||
|
$text = sprintf(
|
||||||
|
"%s的最新网址是:%s",
|
||||||
|
config('v2board.app_name', 'V2Board'),
|
||||||
|
config('v2board.app_url')
|
||||||
|
);
|
||||||
|
$telegramService->sendMessage($msg->chat_id, $text, 'markdown');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class AuthController extends Controller
|
|||||||
$user = new User();
|
$user = new User();
|
||||||
$user->email = $email;
|
$user->email = $email;
|
||||||
$user->password = password_hash($password, PASSWORD_DEFAULT);
|
$user->password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
$user->v2ray_uuid = Helper::guid(true);
|
$user->uuid = Helper::guid(true);
|
||||||
$user->token = Helper::guid();
|
$user->token = Helper::guid();
|
||||||
if ($request->input('invite_code')) {
|
if ($request->input('invite_code')) {
|
||||||
$inviteCode = InviteCode::where('code', $request->input('invite_code'))
|
$inviteCode = InviteCode::where('code', $request->input('invite_code'))
|
||||||
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Server;
|
|||||||
|
|
||||||
use App\Services\ServerService;
|
use App\Services\ServerService;
|
||||||
use App\Services\UserService;
|
use App\Services\UserService;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -13,10 +14,12 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* V2ray Aurora
|
||||||
|
* Github: https://github.com/tokumeikoi/aurora
|
||||||
|
*/
|
||||||
class DeepbworkController extends Controller
|
class DeepbworkController extends Controller
|
||||||
{
|
{
|
||||||
CONST SERVER_CONFIG = '{"api":{"services":["HandlerService","StatsService"],"tag":"api"},"stats":{},"inbound":{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled": true,"destOverride": ["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},"inboundDetour":[{"listen":"0.0.0.0","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"outbound":{"protocol":"freedom","settings":{}},"outboundDetour":[{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"inboundTag":"api","outboundTag":"api","type":"field"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
|
|
||||||
|
|
||||||
public function __construct(Request $request)
|
public function __construct(Request $request)
|
||||||
{
|
{
|
||||||
$token = $request->input('token');
|
$token = $request->input('token');
|
||||||
@ -36,18 +39,18 @@ class DeepbworkController extends Controller
|
|||||||
if (!$server) {
|
if (!$server) {
|
||||||
abort(500, 'fail');
|
abort(500, 'fail');
|
||||||
}
|
}
|
||||||
Cache::put('server_last_check_at_' . $server->id, time());
|
Cache::put(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $server->id), time(), 3600);
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
$users = $serverService->getAvailableUsers(json_decode($server->group_id));
|
$users = $serverService->getAvailableUsers(json_decode($server->group_id));
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
$user->v2ray_user = [
|
$user->v2ray_user = [
|
||||||
"uuid" => $user->v2ray_uuid,
|
"uuid" => $user->uuid,
|
||||||
"email" => sprintf("%s@v2board.user", $user->v2ray_uuid),
|
"email" => sprintf("%s@v2board.user", $user->uuid),
|
||||||
"alter_id" => $user->v2ray_alter_id,
|
"alter_id" => $user->v2ray_alter_id,
|
||||||
"level" => $user->v2ray_level,
|
"level" => $user->v2ray_level,
|
||||||
];
|
];
|
||||||
unset($user['v2ray_uuid']);
|
unset($user['uuid']);
|
||||||
unset($user['v2ray_alter_id']);
|
unset($user['v2ray_alter_id']);
|
||||||
unset($user['v2ray_level']);
|
unset($user['v2ray_level']);
|
||||||
array_push($result, $user);
|
array_push($result, $user);
|
||||||
@ -71,6 +74,7 @@ class DeepbworkController extends Controller
|
|||||||
}
|
}
|
||||||
$data = file_get_contents('php://input');
|
$data = file_get_contents('php://input');
|
||||||
$data = json_decode($data, true);
|
$data = json_decode($data, true);
|
||||||
|
Cache::put(CacheKey::get('SERVER_V2RAY_ONLINE_USER', $server->id), count($data), 3600);
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
$userService = new UserService();
|
$userService = new UserService();
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
@ -88,7 +92,8 @@ class DeepbworkController extends Controller
|
|||||||
$request->input('node_id'),
|
$request->input('node_id'),
|
||||||
$item['u'],
|
$item['u'],
|
||||||
$item['d'],
|
$item['d'],
|
||||||
$server->rate
|
$server->rate,
|
||||||
|
'vmess'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +113,7 @@ class DeepbworkController extends Controller
|
|||||||
}
|
}
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
try {
|
try {
|
||||||
$json = $serverService->getConfig($nodeId, $localPort);
|
$json = $serverService->getVmessConfig($nodeId, $localPort);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
abort(500, $e->getMessage());
|
abort(500, $e->getMessage());
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Server;
|
|||||||
|
|
||||||
use App\Services\ServerService;
|
use App\Services\ServerService;
|
||||||
use App\Services\UserService;
|
use App\Services\UserService;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -13,10 +14,12 @@ use App\Models\ServerLog;
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* V2ray Poseidon
|
||||||
|
* Github: https://github.com/ColetteContreras/trojan-poseidon
|
||||||
|
*/
|
||||||
class PoseidonController extends Controller
|
class PoseidonController extends Controller
|
||||||
{
|
{
|
||||||
CONST SERVER_CONFIG = '{"api":{"services":["HandlerService","StatsService"],"tag":"api"},"stats":{},"inbound":{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled": true,"destOverride": ["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},"inboundDetour":[{"listen":"0.0.0.0","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"outbound":{"protocol":"freedom","settings":{}},"outboundDetour":[{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"inboundTag":"api","outboundTag":"api","type":"field"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
|
|
||||||
|
|
||||||
public $poseidonVersion;
|
public $poseidonVersion;
|
||||||
|
|
||||||
public function __construct(Request $request)
|
public function __construct(Request $request)
|
||||||
@ -34,18 +37,18 @@ class PoseidonController extends Controller
|
|||||||
if (!$server) {
|
if (!$server) {
|
||||||
return $this->error("server could not be found", 404);
|
return $this->error("server could not be found", 404);
|
||||||
}
|
}
|
||||||
Cache::put('server_last_check_at_' . $server->id, time());
|
Cache::put(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $server->id), time(), 3600);
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
$users = $serverService->getAvailableUsers(json_decode($server->group_id));
|
$users = $serverService->getAvailableUsers(json_decode($server->group_id));
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
$user->v2ray_user = [
|
$user->v2ray_user = [
|
||||||
"uuid" => $user->v2ray_uuid,
|
"uuid" => $user->uuid,
|
||||||
"email" => sprintf("%s@v2board.user", $user->v2ray_uuid),
|
"email" => sprintf("%s@v2board.user", $user->uuid),
|
||||||
"alter_id" => $user->v2ray_alter_id,
|
"alter_id" => $user->v2ray_alter_id,
|
||||||
"level" => $user->v2ray_level,
|
"level" => $user->v2ray_level,
|
||||||
];
|
];
|
||||||
unset($user['v2ray_uuid']);
|
unset($user['uuid']);
|
||||||
unset($user['v2ray_alter_id']);
|
unset($user['v2ray_alter_id']);
|
||||||
unset($user['v2ray_level']);
|
unset($user['v2ray_level']);
|
||||||
array_push($result, $user);
|
array_push($result, $user);
|
||||||
@ -58,14 +61,13 @@ class PoseidonController extends Controller
|
|||||||
public function submit(Request $request)
|
public function submit(Request $request)
|
||||||
{
|
{
|
||||||
if ($r = $this->verifyToken($request)) { return $r; }
|
if ($r = $this->verifyToken($request)) { return $r; }
|
||||||
|
|
||||||
// Log::info('serverSubmitData:' . $request->input('node_id') . ':' . file_get_contents('php://input'));
|
|
||||||
$server = Server::find($request->input('node_id'));
|
$server = Server::find($request->input('node_id'));
|
||||||
if (!$server) {
|
if (!$server) {
|
||||||
return $this->error("server could not be found", 404);
|
return $this->error("server could not be found", 404);
|
||||||
}
|
}
|
||||||
$data = file_get_contents('php://input');
|
$data = file_get_contents('php://input');
|
||||||
$data = json_decode($data, true);
|
$data = json_decode($data, true);
|
||||||
|
Cache::put(CacheKey::get('SERVER_V2RAY_ONLINE_USER', $server->id), count($data), 3600);
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
$userService = new UserService();
|
$userService = new UserService();
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
@ -80,7 +82,8 @@ class PoseidonController extends Controller
|
|||||||
$request->input('node_id'),
|
$request->input('node_id'),
|
||||||
$item['u'],
|
$item['u'],
|
||||||
$item['d'],
|
$item['d'],
|
||||||
$server->rate
|
$server->rate,
|
||||||
|
'vmess'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +103,7 @@ class PoseidonController extends Controller
|
|||||||
|
|
||||||
$serverService = new ServerService();
|
$serverService = new ServerService();
|
||||||
try {
|
try {
|
||||||
$json = $serverService->getConfig($nodeId, $localPort);
|
$json = $serverService->getVmessConfig($nodeId, $localPort);
|
||||||
$json->poseidon = [
|
$json->poseidon = [
|
||||||
'license_key' => (string)config('v2board.server_license'),
|
'license_key' => (string)config('v2board.server_license'),
|
||||||
];
|
];
|
||||||
|
120
app/Http/Controllers/Server/TrojanTidalabController.php
Normal file
120
app/Http/Controllers/Server/TrojanTidalabController.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Server;
|
||||||
|
|
||||||
|
use App\Services\ServerService;
|
||||||
|
use App\Services\UserService;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\ServerTrojan;
|
||||||
|
use App\Models\ServerLog;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tidal Lab Trojan
|
||||||
|
* Github: https://github.com/tokumeikoi/tidalab-trojan
|
||||||
|
*/
|
||||||
|
class TrojanTidalabController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$token = $request->input('token');
|
||||||
|
if (empty($token)) {
|
||||||
|
abort(500, 'token is null');
|
||||||
|
}
|
||||||
|
if ($token !== config('v2board.server_token')) {
|
||||||
|
abort(500, 'token is error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后端获取用户
|
||||||
|
public function user(Request $request)
|
||||||
|
{
|
||||||
|
$nodeId = $request->input('node_id');
|
||||||
|
$server = ServerTrojan::find($nodeId);
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, 'fail');
|
||||||
|
}
|
||||||
|
Cache::put(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server->id), time(), 3600);
|
||||||
|
$serverService = new ServerService();
|
||||||
|
$users = $serverService->getAvailableUsers(json_decode($server->group_id));
|
||||||
|
$result = [];
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$user->trojan_user = [
|
||||||
|
"password" => $user->uuid,
|
||||||
|
];
|
||||||
|
unset($user['uuid']);
|
||||||
|
unset($user['v2ray_alter_id']);
|
||||||
|
unset($user['v2ray_level']);
|
||||||
|
array_push($result, $user);
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'msg' => 'ok',
|
||||||
|
'data' => $result,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后端提交数据
|
||||||
|
public function submit(Request $request)
|
||||||
|
{
|
||||||
|
// Log::info('serverSubmitData:' . $request->input('node_id') . ':' . file_get_contents('php://input'));
|
||||||
|
$server = ServerTrojan::find($request->input('node_id'));
|
||||||
|
if (!$server) {
|
||||||
|
return response([
|
||||||
|
'ret' => 0,
|
||||||
|
'msg' => 'server is not found'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$data = file_get_contents('php://input');
|
||||||
|
$data = json_decode($data, true);
|
||||||
|
Cache::put(CacheKey::get('SERVER_TROJAN_ONLINE_USER', $server->id), count($data), 3600);
|
||||||
|
$serverService = new ServerService();
|
||||||
|
$userService = new UserService();
|
||||||
|
foreach ($data as $item) {
|
||||||
|
$u = $item['u'] * $server->rate;
|
||||||
|
$d = $item['d'] * $server->rate;
|
||||||
|
if (!$userService->trafficFetch($u, $d, $item['user_id'])) {
|
||||||
|
return response([
|
||||||
|
'ret' => 0,
|
||||||
|
'msg' => 'user fetch fail'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$serverService->log(
|
||||||
|
$item['user_id'],
|
||||||
|
$request->input('node_id'),
|
||||||
|
$item['u'],
|
||||||
|
$item['d'],
|
||||||
|
$server->rate,
|
||||||
|
'trojan'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response([
|
||||||
|
'ret' => 1,
|
||||||
|
'msg' => 'ok'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后端获取配置
|
||||||
|
public function config(Request $request)
|
||||||
|
{
|
||||||
|
$nodeId = $request->input('node_id');
|
||||||
|
$localPort = $request->input('local_port');
|
||||||
|
if (empty($nodeId) || empty($localPort)) {
|
||||||
|
abort(500, '参数错误');
|
||||||
|
}
|
||||||
|
$serverService = new ServerService();
|
||||||
|
try {
|
||||||
|
$json = $serverService->getTrojanConfig($nodeId, $localPort);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
abort(500, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
die(json_encode($json, JSON_UNESCAPED_UNICODE));
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,8 @@ class CommController extends Controller
|
|||||||
{
|
{
|
||||||
return response([
|
return response([
|
||||||
'data' => [
|
'data' => [
|
||||||
'isTelegram' => (int)config('v2board.telegram_bot_enable', 0)
|
'isTelegram' => (int)config('v2board.telegram_bot_enable', 0),
|
||||||
|
'stripePk' => config('v2board.stripe_pk_live')
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,13 @@ class CouponController extends Controller
|
|||||||
if (time() > $coupon->ended_at) {
|
if (time() > $coupon->ended_at) {
|
||||||
abort(500, '优惠券已过期');
|
abort(500, '优惠券已过期');
|
||||||
}
|
}
|
||||||
|
if ($coupon->limit_plan_ids) {
|
||||||
|
$limitPlanIds = json_decode($coupon->limit_plan_ids);
|
||||||
|
info($limitPlanIds);
|
||||||
|
if (!in_array($request->input('plan_id'), $limitPlanIds)) {
|
||||||
|
abort(500, '这个计划无法使用该优惠码');
|
||||||
|
}
|
||||||
|
}
|
||||||
return response([
|
return response([
|
||||||
'data' => $coupon
|
'data' => $coupon
|
||||||
]);
|
]);
|
||||||
|
@ -9,12 +9,10 @@ use App\Services\OrderService;
|
|||||||
use App\Services\UserService;
|
use App\Services\UserService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\Plan;
|
use App\Models\Plan;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Coupon;
|
|
||||||
use App\Utils\Helper;
|
use App\Utils\Helper;
|
||||||
use Omnipay\Omnipay;
|
use Omnipay\Omnipay;
|
||||||
use Stripe\Stripe;
|
use Stripe\Stripe;
|
||||||
@ -173,7 +171,7 @@ class OrderController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
switch ($method) {
|
switch ($method) {
|
||||||
// return type => 0: QRCode / 1: URL
|
// return type => 0: QRCode / 1: URL / 2: No action
|
||||||
case 0:
|
case 0:
|
||||||
// alipayF2F
|
// alipayF2F
|
||||||
if (!(int)config('v2board.alipay_enable')) {
|
if (!(int)config('v2board.alipay_enable')) {
|
||||||
@ -218,6 +216,14 @@ class OrderController extends Controller
|
|||||||
'type' => 1,
|
'type' => 1,
|
||||||
'data' => $this->payTaro($order)
|
'data' => $this->payTaro($order)
|
||||||
]);
|
]);
|
||||||
|
case 6:
|
||||||
|
if (!(int)config('v2board.stripe_card_enable')) {
|
||||||
|
abort(500, '支付方式不可用');
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'type' => 2,
|
||||||
|
'data' => $this->stripeCard($order, $request->input('token'))
|
||||||
|
]);
|
||||||
default:
|
default:
|
||||||
abort(500, '支付方式不存在');
|
abort(500, '支付方式不存在');
|
||||||
}
|
}
|
||||||
@ -266,7 +272,7 @@ class OrderController extends Controller
|
|||||||
|
|
||||||
if ((int)config('v2board.bitpayx_enable')) {
|
if ((int)config('v2board.bitpayx_enable')) {
|
||||||
$bitpayX = new \StdClass();
|
$bitpayX = new \StdClass();
|
||||||
$bitpayX->name = config('v2board.bitpayx_name', '聚合支付');
|
$bitpayX->name = config('v2board.bitpayx_name', '在线支付');
|
||||||
$bitpayX->method = 4;
|
$bitpayX->method = 4;
|
||||||
$bitpayX->icon = 'wallet';
|
$bitpayX->icon = 'wallet';
|
||||||
array_push($data, $bitpayX);
|
array_push($data, $bitpayX);
|
||||||
@ -274,12 +280,20 @@ class OrderController extends Controller
|
|||||||
|
|
||||||
if ((int)config('v2board.paytaro_enable')) {
|
if ((int)config('v2board.paytaro_enable')) {
|
||||||
$obj = new \StdClass();
|
$obj = new \StdClass();
|
||||||
$obj->name = config('v2board.paytaro_name', '聚合支付');
|
$obj->name = config('v2board.paytaro_name', '在线支付');
|
||||||
$obj->method = 5;
|
$obj->method = 5;
|
||||||
$obj->icon = 'wallet';
|
$obj->icon = 'wallet';
|
||||||
array_push($data, $obj);
|
array_push($data, $obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((int)config('v2board.stripe_card_enable')) {
|
||||||
|
$obj = new \StdClass();
|
||||||
|
$obj->name = '信用卡';
|
||||||
|
$obj->method = 6;
|
||||||
|
$obj->icon = 'card';
|
||||||
|
array_push($data, $obj);
|
||||||
|
}
|
||||||
|
|
||||||
return response([
|
return response([
|
||||||
'data' => $data
|
'data' => $data
|
||||||
]);
|
]);
|
||||||
@ -347,7 +361,7 @@ class OrderController extends Controller
|
|||||||
'statement_descriptor' => $order->trade_no,
|
'statement_descriptor' => $order->trade_no,
|
||||||
'metadata' => [
|
'metadata' => [
|
||||||
'user_id' => $order->user_id,
|
'user_id' => $order->user_id,
|
||||||
'invoice_id' => $order->trade_no,
|
'out_trade_no' => $order->trade_no,
|
||||||
'identifier' => ''
|
'identifier' => ''
|
||||||
],
|
],
|
||||||
'redirect' => [
|
'redirect' => [
|
||||||
@ -357,10 +371,6 @@ class OrderController extends Controller
|
|||||||
if (!$source['redirect']['url']) {
|
if (!$source['redirect']['url']) {
|
||||||
abort(500, '支付网关请求失败');
|
abort(500, '支付网关请求失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Cache::put($source['id'], $order->trade_no, 3600)) {
|
|
||||||
abort(500, '订单创建失败');
|
|
||||||
}
|
|
||||||
return $source['redirect']['url'];
|
return $source['redirect']['url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +388,7 @@ class OrderController extends Controller
|
|||||||
'type' => 'wechat',
|
'type' => 'wechat',
|
||||||
'metadata' => [
|
'metadata' => [
|
||||||
'user_id' => $order->user_id,
|
'user_id' => $order->user_id,
|
||||||
'invoice_id' => $order->trade_no,
|
'out_trade_no' => $order->trade_no,
|
||||||
'identifier' => ''
|
'identifier' => ''
|
||||||
],
|
],
|
||||||
'redirect' => [
|
'redirect' => [
|
||||||
@ -388,12 +398,38 @@ class OrderController extends Controller
|
|||||||
if (!$source['wechat']['qr_code_url']) {
|
if (!$source['wechat']['qr_code_url']) {
|
||||||
abort(500, '支付网关请求失败');
|
abort(500, '支付网关请求失败');
|
||||||
}
|
}
|
||||||
if (!Cache::put($source['id'], $order->trade_no, 3600)) {
|
|
||||||
abort(500, '订单创建失败');
|
|
||||||
}
|
|
||||||
return $source['wechat']['qr_code_url'];
|
return $source['wechat']['qr_code_url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function stripeCard($order, string $token)
|
||||||
|
{
|
||||||
|
$currency = config('v2board.stripe_currency', 'hkd');
|
||||||
|
$exchange = Helper::exchange('CNY', strtoupper($currency));
|
||||||
|
if (!$exchange) {
|
||||||
|
abort(500, '货币转换超时,请稍后再试');
|
||||||
|
}
|
||||||
|
Stripe::setApiKey(config('v2board.stripe_sk_live'));
|
||||||
|
try {
|
||||||
|
$charge = \Stripe\Charge::create([
|
||||||
|
'amount' => floor($order->total_amount * $exchange),
|
||||||
|
'currency' => $currency,
|
||||||
|
'source' => $token,
|
||||||
|
'metadata' => [
|
||||||
|
'user_id' => $order->user_id,
|
||||||
|
'out_trade_no' => $order->trade_no,
|
||||||
|
'identifier' => ''
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
abort(500, '遇到了点问题,请刷新页面稍后再试');
|
||||||
|
}
|
||||||
|
info($charge);
|
||||||
|
if (!$charge->paid) {
|
||||||
|
abort(500, '扣款失败,请检查信用卡信息');
|
||||||
|
}
|
||||||
|
return $charge->paid;
|
||||||
|
}
|
||||||
|
|
||||||
private function bitpayX($order)
|
private function bitpayX($order)
|
||||||
{
|
{
|
||||||
$bitpayX = new BitpayX(config('v2board.bitpayx_appsecret'));
|
$bitpayX = new BitpayX(config('v2board.bitpayx_appsecret'));
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
namespace App\Http\Controllers\User;
|
namespace App\Http\Controllers\User;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Services\ServerService;
|
||||||
use App\Services\UserService;
|
use App\Services\UserService;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
@ -17,29 +19,15 @@ class ServerController extends Controller
|
|||||||
public function fetch(Request $request)
|
public function fetch(Request $request)
|
||||||
{
|
{
|
||||||
$user = User::find($request->session()->get('id'));
|
$user = User::find($request->session()->get('id'));
|
||||||
$server = [];
|
$servers = [];
|
||||||
$userService = new UserService();
|
$userService = new UserService();
|
||||||
if ($userService->isAvailable($user)) {
|
if ($userService->isAvailable($user)) {
|
||||||
$servers = Server::where('show', 1)
|
$serverService = new ServerService();
|
||||||
->orderBy('sort', 'ASC')
|
$servers = $serverService->getAllServers($user);
|
||||||
->get();
|
$servers = array_merge($servers['vmess'], $servers['trojan']);
|
||||||
foreach ($servers as $item) {
|
|
||||||
$groupId = json_decode($item['group_id']);
|
|
||||||
if (in_array($user->group_id, $groupId)) {
|
|
||||||
array_push($server, $item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ($i = 0; $i < count($server); $i++) {
|
|
||||||
$server[$i]['link'] = Helper::buildVmessLink($server[$i], $user);
|
|
||||||
if ($server[$i]['parent_id']) {
|
|
||||||
$server[$i]['last_check_at'] = Cache::get('server_last_check_at_' . $server[$i]['parent_id']);
|
|
||||||
} else {
|
|
||||||
$server[$i]['last_check_at'] = Cache::get('server_last_check_at_' . $server[$i]['id']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return response([
|
return response([
|
||||||
'data' => $server
|
'data' => $servers
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ class UserController extends Controller
|
|||||||
public function resetSecurity(Request $request)
|
public function resetSecurity(Request $request)
|
||||||
{
|
{
|
||||||
$user = User::find($request->session()->get('id'));
|
$user = User::find($request->session()->get('id'));
|
||||||
$user->v2ray_uuid = Helper::guid(true);
|
$user->uuid = Helper::guid(true);
|
||||||
$user->token = Helper::guid();
|
$user->token = Helper::guid();
|
||||||
if (!$user->save()) {
|
if (!$user->save()) {
|
||||||
abort(500, '重置失败');
|
abort(500, '重置失败');
|
||||||
|
@ -44,6 +44,7 @@ class ConfigSave extends FormRequest
|
|||||||
// stripe
|
// stripe
|
||||||
'stripe_alipay_enable' => 'in:0,1',
|
'stripe_alipay_enable' => 'in:0,1',
|
||||||
'stripe_wepay_enable' => 'in:0,1',
|
'stripe_wepay_enable' => 'in:0,1',
|
||||||
|
'stripe_card_enable' => 'in:0,1',
|
||||||
'stripe_sk_live' => '',
|
'stripe_sk_live' => '',
|
||||||
'stripe_pk_live' => '',
|
'stripe_pk_live' => '',
|
||||||
'stripe_webhook_key' => '',
|
'stripe_webhook_key' => '',
|
||||||
|
@ -6,6 +6,16 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
|
|
||||||
class CouponSave extends FormRequest
|
class CouponSave extends FormRequest
|
||||||
{
|
{
|
||||||
|
const RULES = [
|
||||||
|
'name' => 'required',
|
||||||
|
'type' => 'required|in:1,2',
|
||||||
|
'value' => 'required|integer',
|
||||||
|
'started_at' => 'required|integer',
|
||||||
|
'ended_at' => 'required|integer',
|
||||||
|
'limit_use' => 'nullable|integer',
|
||||||
|
'limit_plan_ids' => 'nullable|array',
|
||||||
|
'code' => ''
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
@ -13,14 +23,7 @@ class CouponSave extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return self::RULES;
|
||||||
'name' => 'required',
|
|
||||||
'type' => 'required|in:1,2',
|
|
||||||
'value' => 'required|integer',
|
|
||||||
'started_at' => 'required|integer',
|
|
||||||
'ended_at' => 'required|integer',
|
|
||||||
'limit_use' => 'nullable|integer'
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function messages()
|
public function messages()
|
||||||
@ -35,7 +38,8 @@ class CouponSave extends FormRequest
|
|||||||
'started_at.integer' => '开始时间格式有误',
|
'started_at.integer' => '开始时间格式有误',
|
||||||
'ended_at.required' => '结束时间不能为空',
|
'ended_at.required' => '结束时间不能为空',
|
||||||
'ended_at.integer' => '结束时间格式有误',
|
'ended_at.integer' => '结束时间格式有误',
|
||||||
'limit_use.integer' => '使用次数格式有误'
|
'limit_use.integer' => '使用次数格式有误',
|
||||||
|
'limit_plan_ids.array' => '指定订阅格式有误'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
app/Http/Requests/Admin/ServerTrojanSave.php
Normal file
48
app/Http/Requests/Admin/ServerTrojanSave.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ServerTrojanSave extends FormRequest
|
||||||
|
{
|
||||||
|
CONST RULES = [
|
||||||
|
'show' => '',
|
||||||
|
'name' => 'required',
|
||||||
|
'group_id' => 'required|array',
|
||||||
|
'parent_id' => 'nullable|integer',
|
||||||
|
'host' => 'required',
|
||||||
|
'port' => 'required',
|
||||||
|
'server_port' => 'required',
|
||||||
|
'allow_insecure' => 'nullable|in:0,1',
|
||||||
|
'server_name' => 'nullable',
|
||||||
|
'tags' => 'nullable|array',
|
||||||
|
'rate' => 'required|numeric'
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return self::RULES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name.required' => '节点名称不能为空',
|
||||||
|
'group_id.required' => '权限组不能为空',
|
||||||
|
'group_id.array' => '权限组格式不正确',
|
||||||
|
'parent_id.integer' => '父节点格式不正确',
|
||||||
|
'host.required' => '节点地址不能为空',
|
||||||
|
'port.required' => '连接端口不能为空',
|
||||||
|
'server_port.required' => '后端服务端口不能为空',
|
||||||
|
'allow_insecure.in' => '允许不安全格式不正确',
|
||||||
|
'tags.array' => '标签格式不正确',
|
||||||
|
'rate.required' => '倍率不能为空',
|
||||||
|
'rate.numeric' => '倍率格式不正确'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
28
app/Http/Requests/Admin/ServerTrojanSort.php
Normal file
28
app/Http/Requests/Admin/ServerTrojanSort.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ServerTrojanSort extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'server_ids' => 'required|array'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'server_ids.required' => '服务器ID不能为空',
|
||||||
|
'server_ids.array' => '服务器ID格式有误'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
28
app/Http/Requests/Admin/ServerTrojanUpdate.php
Executable file
28
app/Http/Requests/Admin/ServerTrojanUpdate.php
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ServerTrojanUpdate extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'show' => 'in:0,1'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'show.in' => '显示状态格式不正确'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ namespace App\Http\Requests\Admin;
|
|||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class ServerSave extends FormRequest
|
class ServerV2raySave extends FormRequest
|
||||||
{
|
{
|
||||||
CONST RULES = [
|
CONST RULES = [
|
||||||
'show' => '',
|
'show' => '',
|
@ -4,7 +4,7 @@ namespace App\Http\Requests\Admin;
|
|||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class ServerSort extends FormRequest
|
class ServerV2raySort extends FormRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
@ -4,7 +4,7 @@ namespace App\Http\Requests\Admin;
|
|||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class ServerUpdate extends FormRequest
|
class ServerV2rayUpdate extends FormRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
@ -23,16 +23,31 @@ class AdminRoute
|
|||||||
$router->post('/plan/update', 'Admin\\PlanController@update');
|
$router->post('/plan/update', 'Admin\\PlanController@update');
|
||||||
$router->post('/plan/sort', 'Admin\\PlanController@sort');
|
$router->post('/plan/sort', 'Admin\\PlanController@sort');
|
||||||
// Server
|
// Server
|
||||||
$router->get ('/server/fetch', 'Admin\\ServerController@fetch');
|
$router->get ('/server/group/fetch', 'Admin\\Server\\GroupController@fetch');
|
||||||
$router->post('/server/save', 'Admin\\ServerController@save');
|
$router->post('/server/group/save', 'Admin\\Server\\GroupController@save');
|
||||||
$router->get ('/server/group/fetch', 'Admin\\ServerController@groupFetch');
|
$router->post('/server/group/drop', 'Admin\\Server\\GroupController@drop');
|
||||||
$router->post('/server/group/save', 'Admin\\ServerController@groupSave');
|
$router->group([
|
||||||
$router->post('/server/group/drop', 'Admin\\ServerController@groupDrop');
|
'prefix' => 'server/trojan'
|
||||||
$router->post('/server/drop', 'Admin\\ServerController@drop');
|
], function ($router) {
|
||||||
$router->post('/server/update', 'Admin\\ServerController@update');
|
$router->get ('fetch', 'Admin\\Server\\TrojanController@fetch');
|
||||||
$router->post('/server/copy', 'Admin\\ServerController@copy');
|
$router->post('save', 'Admin\\Server\\TrojanController@save');
|
||||||
$router->post('/server/viewConfig', 'Admin\\ServerController@viewConfig');
|
$router->post('drop', 'Admin\\Server\\TrojanController@drop');
|
||||||
$router->post('/server/sort', 'Admin\\ServerController@sort');
|
$router->post('update', 'Admin\\Server\\TrojanController@update');
|
||||||
|
$router->post('copy', 'Admin\\Server\\TrojanController@copy');
|
||||||
|
$router->post('sort', 'Admin\\Server\\TrojanController@sort');
|
||||||
|
$router->post('viewConfig', 'Admin\\Server\\TrojanController@viewConfig');
|
||||||
|
});
|
||||||
|
$router->group([
|
||||||
|
'prefix' => 'server/v2ray'
|
||||||
|
], function ($router) {
|
||||||
|
$router->get ('fetch', 'Admin\\Server\\V2rayController@fetch');
|
||||||
|
$router->post('save', 'Admin\\Server\\V2rayController@save');
|
||||||
|
$router->post('drop', 'Admin\\Server\\V2rayController@drop');
|
||||||
|
$router->post('update', 'Admin\\Server\\V2rayController@update');
|
||||||
|
$router->post('copy', 'Admin\\Server\\V2rayController@copy');
|
||||||
|
$router->post('sort', 'Admin\\Server\\V2rayController@sort');
|
||||||
|
$router->post('viewConfig', 'Admin\\Server\\V2rayController@viewConfig');
|
||||||
|
});
|
||||||
// Order
|
// Order
|
||||||
$router->get ('/order/fetch', 'Admin\\OrderController@fetch');
|
$router->get ('/order/fetch', 'Admin\\OrderController@fetch');
|
||||||
$router->post('/order/repair', 'Admin\\OrderController@repair');
|
$router->post('/order/repair', 'Admin\\OrderController@repair');
|
||||||
|
@ -14,8 +14,9 @@ class ClientRoute
|
|||||||
// Client
|
// Client
|
||||||
$router->get('/subscribe', 'Client\\ClientController@subscribe');
|
$router->get('/subscribe', 'Client\\ClientController@subscribe');
|
||||||
// App
|
// App
|
||||||
$router->get('/app/data', 'Client\\AppController@data');
|
|
||||||
$router->get('/app/config', 'Client\\AppController@config');
|
$router->get('/app/config', 'Client\\AppController@config');
|
||||||
|
$router->get('/app/getConfig', 'Client\\AppController@getConfig');
|
||||||
|
$router->get('/app/getVersion', 'Client\\AppController@getVersion');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,4 @@ class ServerLog extends Model
|
|||||||
{
|
{
|
||||||
protected $table = 'v2_server_log';
|
protected $table = 'v2_server_log';
|
||||||
protected $dateFormat = 'U';
|
protected $dateFormat = 'U';
|
||||||
protected $dispatchesEvents = [
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
12
app/Models/ServerStat.php
Normal file
12
app/Models/ServerStat.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class ServerStat extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'v2_server_stat';
|
||||||
|
protected $dateFormat = 'U';
|
||||||
|
protected $guarded = ['id'];
|
||||||
|
}
|
12
app/Models/ServerTrojan.php
Normal file
12
app/Models/ServerTrojan.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class ServerTrojan extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'v2_server_trojan';
|
||||||
|
protected $dateFormat = 'U';
|
||||||
|
protected $guarded = ['id'];
|
||||||
|
}
|
@ -43,6 +43,12 @@ class CouponService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($this->coupon->limit_plan_ids) {
|
||||||
|
$limitPlanIds = json_decode($this->coupon->limit_plan_ids);
|
||||||
|
if (!in_array($order->plan_id, $limitPlanIds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,25 +119,43 @@ class OrderService
|
|||||||
'month_price' => 1,
|
'month_price' => 1,
|
||||||
'quarter_price' => 3,
|
'quarter_price' => 3,
|
||||||
'half_year_price' => 6,
|
'half_year_price' => 6,
|
||||||
'year_price' => 12,
|
'year_price' => 12
|
||||||
'onetime_price' => 0
|
|
||||||
];
|
];
|
||||||
$orderModel = Order::where('user_id', $user->id)
|
$orderModel = Order::where('user_id', $user->id)
|
||||||
->where('cycle', '!=', 'reset_price')
|
->where('cycle', '!=', 'reset_price')
|
||||||
->where('status', 3);
|
->where('status', 3);
|
||||||
$surplusAmount = 0;
|
$orderSurplusMonth = 0;
|
||||||
|
$orderSurplusAmount = 0;
|
||||||
|
$userSurplusMonth = ($user->expired_at - time()) / 2678400;
|
||||||
foreach ($orderModel->get() as $item) {
|
foreach ($orderModel->get() as $item) {
|
||||||
$surplusMonth = strtotime("+ {$strToMonth[$item->cycle]}month", $item->created_at->format('U'));
|
// 兼容历史余留问题
|
||||||
if (!$surplusMonth) continue;
|
if ($item->cycle === 'onetime_price') continue;
|
||||||
$surplusMonth = ($surplusMonth - time()) / 2678400 / $strToMonth[$item->cycle];
|
$orderSurplusMonth = $orderSurplusMonth + $strToMonth[$item->cycle];
|
||||||
if ($surplusMonth > 0) {
|
$orderSurplusAmount = $orderSurplusAmount + ($item['total_amount'] + $item['balance_amount']);
|
||||||
$surplusAmount = $surplusAmount + ($item['total_amount'] + $item['balance_amount']) * $surplusMonth;
|
|
||||||
}
|
}
|
||||||
|
if (!$orderSurplusMonth || !$orderSurplusAmount) return;
|
||||||
|
$monthUnitPrice = $orderSurplusAmount / $orderSurplusMonth;
|
||||||
|
// 如果用户过期月大于订单过期月
|
||||||
|
if ($userSurplusMonth > $orderSurplusMonth) {
|
||||||
|
$orderSurplusAmount = $orderSurplusMonth * $monthUnitPrice;
|
||||||
|
} else {
|
||||||
|
$orderSurplusAmount = $userSurplusMonth * $monthUnitPrice;
|
||||||
}
|
}
|
||||||
if (!$surplusAmount) {
|
if (!$orderSurplusAmount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$order->surplus_amount = $surplusAmount > 0 ? $surplusAmount : 0;
|
$order->surplus_amount = $orderSurplusAmount > 0 ? $orderSurplusAmount : 0;
|
||||||
$order->surplus_order_ids = json_encode(array_map(function ($v) { return $v['id'];}, $orderModel->get()->toArray()));
|
$order->surplus_order_ids = json_encode(array_map(function ($v) { return $v['id'];}, $orderModel->get()->toArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function success(string $callbackNo)
|
||||||
|
{
|
||||||
|
$order = $this->order;
|
||||||
|
if ($order->status !== 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$order->status = 1;
|
||||||
|
$order->callback_no = $callbackNo;
|
||||||
|
return $order->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,72 @@ namespace App\Services;
|
|||||||
use App\Models\ServerLog;
|
use App\Models\ServerLog;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use App\Models\ServerTrojan;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
|
use App\Utils\Helper;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class ServerService
|
class ServerService
|
||||||
{
|
{
|
||||||
|
|
||||||
CONST SERVER_CONFIG = '{"api":{"services":["HandlerService","StatsService"],"tag":"api"},"dns":{},"stats":{},"inbound":{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled":true,"destOverride":["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},"inboundDetour":[{"listen":"0.0.0.0","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"outbound":{"protocol":"freedom","settings":{}},"outboundDetour":[{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"inboundTag":"api","outboundTag":"api","type":"field"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
|
CONST V2RAY_CONFIG = '{"api":{"services":["HandlerService","StatsService"],"tag":"api"},"dns":{},"stats":{},"inbound":{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled":true,"destOverride":["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},"inboundDetour":[{"listen":"0.0.0.0","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"outbound":{"protocol":"freedom","settings":{}},"outboundDetour":[{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"inboundTag":"api","outboundTag":"api","type":"field"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
|
||||||
|
CONST TROJAN_CONFIG = '{"run_type":"server","local_addr":"0.0.0.0","local_port":443,"remote_addr":"www.taobao.com","remote_port":80,"password":[],"ssl":{"cert":"server.crt","key":"server.key","sni":"domain.com"},"api":{"enabled":true,"api_addr":"127.0.0.1","api_port":10000}}';
|
||||||
|
public function getVmess(User $user, $all = false):array
|
||||||
|
{
|
||||||
|
$vmess = [];
|
||||||
|
$model = Server::orderBy('sort', 'ASC');
|
||||||
|
if (!$all) {
|
||||||
|
$model->where('show', 1);
|
||||||
|
}
|
||||||
|
$vmesss = $model->get();
|
||||||
|
foreach ($vmesss as $k => $v) {
|
||||||
|
$groupId = json_decode($vmesss[$k]['group_id']);
|
||||||
|
if (in_array($user->group_id, $groupId)) {
|
||||||
|
$vmesss[$k]['link'] = Helper::buildVmessLink($vmesss[$k], $user);
|
||||||
|
if ($vmesss[$k]['parent_id']) {
|
||||||
|
$vmesss[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $vmesss[$k]['parent_id']));
|
||||||
|
} else {
|
||||||
|
$vmesss[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_V2RAY_LAST_CHECK_AT', $vmesss[$k]['id']));
|
||||||
|
}
|
||||||
|
array_push($vmess, $vmesss[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $vmess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTrojan(User $user, $all = false)
|
||||||
|
{
|
||||||
|
$trojan = [];
|
||||||
|
$model = ServerTrojan::orderBy('sort', 'ASC');
|
||||||
|
if (!$all) {
|
||||||
|
$model->where('show', 1);
|
||||||
|
}
|
||||||
|
$trojans = $model->get();
|
||||||
|
foreach ($trojans as $k => $v) {
|
||||||
|
$groupId = json_decode($trojans[$k]['group_id']);
|
||||||
|
if (in_array($user->group_id, $groupId)) {
|
||||||
|
if ($trojans[$k]['parent_id']) {
|
||||||
|
$trojans[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojans[$k]['parent_id']));
|
||||||
|
} else {
|
||||||
|
$trojans[$k]['last_check_at'] = Cache::get(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $trojans[$k]['id']));
|
||||||
|
}
|
||||||
|
array_push($trojan, $trojans[$k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return $trojan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllServers(User $user, $all = false)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'vmess' => $this->getVmess($user, $all),
|
||||||
|
'trojan' => $this->getTrojan($user, $all)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getAvailableUsers($groupId)
|
public function getAvailableUsers($groupId)
|
||||||
{
|
{
|
||||||
@ -27,20 +88,20 @@ class ServerService
|
|||||||
'u',
|
'u',
|
||||||
'd',
|
'd',
|
||||||
'transfer_enable',
|
'transfer_enable',
|
||||||
'v2ray_uuid',
|
'uuid',
|
||||||
'v2ray_alter_id',
|
'v2ray_alter_id',
|
||||||
'v2ray_level'
|
'v2ray_level'
|
||||||
])
|
])
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getConfig(int $nodeId, int $localPort)
|
public function getVmessConfig(int $nodeId, int $localPort)
|
||||||
{
|
{
|
||||||
$server = Server::find($nodeId);
|
$server = Server::find($nodeId);
|
||||||
if (!$server) {
|
if (!$server) {
|
||||||
abort(500, '节点不存在');
|
abort(500, '节点不存在');
|
||||||
}
|
}
|
||||||
$json = json_decode(self::SERVER_CONFIG);
|
$json = json_decode(self::V2RAY_CONFIG);
|
||||||
$json->log->loglevel = config('v2board.server_log_level', 'none');
|
$json->log->loglevel = config('v2board.server_log_level', 'none');
|
||||||
$json->inboundDetour[0]->port = (int)$localPort;
|
$json->inboundDetour[0]->port = (int)$localPort;
|
||||||
$json->inbound->port = (int)$server->server_port;
|
$json->inbound->port = (int)$server->server_port;
|
||||||
@ -53,6 +114,22 @@ class ServerService
|
|||||||
return $json;
|
return $json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTrojanConfig(int $nodeId, int $localPort)
|
||||||
|
{
|
||||||
|
$server = ServerTrojan::find($nodeId);
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '节点不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = json_decode(self::TROJAN_CONFIG);
|
||||||
|
$json->local_port = $server->server_port;
|
||||||
|
$json->ssl->sni = $server->server_name ? $server->server_name : $server->host;
|
||||||
|
$json->ssl->cert = "/root/.cert/server.crt";
|
||||||
|
$json->ssl->key = "/root/.cert/server.key";
|
||||||
|
$json->api->api_port = $localPort;
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
private function setDns(Server $server, object $json)
|
private function setDns(Server $server, object $json)
|
||||||
{
|
{
|
||||||
if ($server->dnsSettings) {
|
if ($server->dnsSettings) {
|
||||||
@ -123,8 +200,8 @@ class ServerService
|
|||||||
$tlsSettings = json_decode($server->tlsSettings);
|
$tlsSettings = json_decode($server->tlsSettings);
|
||||||
$json->inbound->streamSettings->security = 'tls';
|
$json->inbound->streamSettings->security = 'tls';
|
||||||
$tls = (object)[
|
$tls = (object)[
|
||||||
'certificateFile' => '/home/v2ray.crt',
|
'certificateFile' => '/root/.cert/server.crt',
|
||||||
'keyFile' => '/home/v2ray.key'
|
'keyFile' => '/root/.cert/server.key'
|
||||||
];
|
];
|
||||||
$json->inbound->streamSettings->tlsSettings = new \StdClass();
|
$json->inbound->streamSettings->tlsSettings = new \StdClass();
|
||||||
if (isset($tlsSettings->serverName)) {
|
if (isset($tlsSettings->serverName)) {
|
||||||
@ -137,7 +214,7 @@ class ServerService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function log(int $userId, int $serverId, int $u, int $d, float $rate)
|
public function log(int $userId, int $serverId, int $u, int $d, float $rate, string $method)
|
||||||
{
|
{
|
||||||
if (($u + $d) <= 10240) return;
|
if (($u + $d) <= 10240) return;
|
||||||
$timestamp = strtotime(date('Y-m-d H:0'));
|
$timestamp = strtotime(date('Y-m-d H:0'));
|
||||||
@ -146,6 +223,7 @@ class ServerService
|
|||||||
->where('server_id', $serverId)
|
->where('server_id', $serverId)
|
||||||
->where('user_id', $userId)
|
->where('user_id', $userId)
|
||||||
->where('rate', $rate)
|
->where('rate', $rate)
|
||||||
|
->where('method', $method)
|
||||||
->first();
|
->first();
|
||||||
if ($serverLog) {
|
if ($serverLog) {
|
||||||
$serverLog->u = $serverLog->u + $u;
|
$serverLog->u = $serverLog->u + $u;
|
||||||
@ -159,6 +237,7 @@ class ServerService
|
|||||||
$serverLog->d = $d;
|
$serverLog->d = $d;
|
||||||
$serverLog->rate = $rate;
|
$serverLog->rate = $rate;
|
||||||
$serverLog->log_at = $timestamp;
|
$serverLog->log_at = $timestamp;
|
||||||
|
$serverLog->method = $method;
|
||||||
$serverLog->save();
|
$serverLog->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,11 @@ class CacheKey
|
|||||||
{
|
{
|
||||||
CONST KEYS = [
|
CONST KEYS = [
|
||||||
'EMAIL_VERIFY_CODE' => '邮箱验证吗',
|
'EMAIL_VERIFY_CODE' => '邮箱验证吗',
|
||||||
'LAST_SEND_EMAIL_VERIFY_TIMESTAMP' => '最后一次发送邮箱验证码时间'
|
'LAST_SEND_EMAIL_VERIFY_TIMESTAMP' => '最后一次发送邮箱验证码时间',
|
||||||
|
'SERVER_V2RAY_ONLINE_USER' => '节点在线用户',
|
||||||
|
'SERVER_V2RAY_LAST_CHECK_AT' => '节点最后检查时间',
|
||||||
|
'SERVER_TROJAN_ONLINE_USER' => 'trojan节点在线用户',
|
||||||
|
'SERVER_TROJAN_LAST_CHECK_AT' => 'trojan节点最后检查时间'
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function get(string $key, $uniqueValue)
|
public static function get(string $key, $uniqueValue)
|
||||||
|
52
app/Utils/Clash.php
Normal file
52
app/Utils/Clash.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
|
||||||
|
class Clash
|
||||||
|
{
|
||||||
|
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'] = 2;
|
||||||
|
$array['cipher'] = 'auto';
|
||||||
|
if ($server->tls) {
|
||||||
|
$tlsSettings = json_decode($server->tlsSettings);
|
||||||
|
$array['tls'] = true;
|
||||||
|
if (isset($tlsSettings->allowInsecure)) $array['skip-cert-verify'] = ($tlsSettings->allowInsecure ? true : false );
|
||||||
|
}
|
||||||
|
if ($server->network == 'ws') {
|
||||||
|
$array['network'] = $server->network;
|
||||||
|
if ($server->networkSettings) {
|
||||||
|
$wsSettings = json_decode($server->networkSettings);
|
||||||
|
if (isset($wsSettings->path)) $array['ws-path'] = $wsSettings->path;
|
||||||
|
if (isset($wsSettings->headers->Host)) $array['ws-headers'] = [
|
||||||
|
'Host' => $wsSettings->headers->Host
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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['sni'] = $server->server_name;
|
||||||
|
if ($server->allow_insecure) {
|
||||||
|
$array['skip-cert-verify'] = true;
|
||||||
|
} else {
|
||||||
|
$array['skip-cert-verify'] = false;
|
||||||
|
}
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Utils;
|
namespace App\Utils;
|
||||||
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use App\Models\ServerTrojan;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
class Helper
|
class Helper
|
||||||
@ -56,6 +57,18 @@ class Helper
|
|||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function buildTrojanLink(ServerTrojan $server, User $user)
|
||||||
|
{
|
||||||
|
$server->name = rawurlencode($server->name);
|
||||||
|
$query = http_build_query([
|
||||||
|
'allowInsecure' => $server->allow_insecure,
|
||||||
|
'peer' => $server->server_name
|
||||||
|
]);
|
||||||
|
$uri = "trojan://{$user->uuid}@{$server->host}:{$server->port}?{$query}#{$server->name}";
|
||||||
|
$uri .= "\r\n";
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
public static function buildVmessLink(Server $server, User $user)
|
public static function buildVmessLink(Server $server, User $user)
|
||||||
{
|
{
|
||||||
$config = [
|
$config = [
|
||||||
@ -63,7 +76,7 @@ class Helper
|
|||||||
"ps" => $server->name,
|
"ps" => $server->name,
|
||||||
"add" => $server->host,
|
"add" => $server->host,
|
||||||
"port" => $server->port,
|
"port" => $server->port,
|
||||||
"id" => $user->v2ray_uuid,
|
"id" => $user->uuid,
|
||||||
"aid" => "2",
|
"aid" => "2",
|
||||||
"net" => $server->network,
|
"net" => $server->network,
|
||||||
"type" => "none",
|
"type" => "none",
|
||||||
|
51
app/Utils/QuantumultX.php
Normal file
51
app/Utils/QuantumultX.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
|
||||||
|
class QuantumultX
|
||||||
|
{
|
||||||
|
public static function buildVmess($uuid, $server)
|
||||||
|
{
|
||||||
|
$uri = "vmess=" . $server->host . ":" . $server->port . ", method=none, password=" . $uuid . ", fast-open=false, udp-relay=false, tag=" . $server->name;
|
||||||
|
if ($server->tls) {
|
||||||
|
$tlsSettings = json_decode($server->tlsSettings);
|
||||||
|
if ($server->network === 'tcp') $uri .= ', obfs=over-tls';
|
||||||
|
if (isset($tlsSettings->allowInsecure)) {
|
||||||
|
// Default: tls-verification=true
|
||||||
|
$uri .= ', tls-verification=' . ($tlsSettings->allowInsecure ? "false" : "true");
|
||||||
|
}
|
||||||
|
if (isset($tlsSettings->serverName)) {
|
||||||
|
$uri .= ', obfs-host=' . $tlsSettings->serverName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($server->network === 'ws') {
|
||||||
|
$uri .= ', obfs=' . ($server->tls ? 'wss' : 'ws');
|
||||||
|
if ($server->networkSettings) {
|
||||||
|
$wsSettings = json_decode($server->networkSettings);
|
||||||
|
if (isset($wsSettings->path)) $uri .= ', obfs-uri=' . $wsSettings->path;
|
||||||
|
if (isset($wsSettings->headers->Host)) $uri .= ', obfs-host=' . $wsSettings->headers->Host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$uri .= "\r\n";
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function buildTrojan($password, $server)
|
||||||
|
{
|
||||||
|
$config = [
|
||||||
|
"trojan={$server->host}:{$server->port}",
|
||||||
|
"password={$password}",
|
||||||
|
"over-tls=true",
|
||||||
|
$server->server_name ? "tls-host={$server->server_name}" : "",
|
||||||
|
$server->allow_insecure ? 'tls-verification=true' : 'tls-verification=false',
|
||||||
|
"fast-open=false",
|
||||||
|
"udp-relay=false",
|
||||||
|
"tag={$server->name}"
|
||||||
|
];
|
||||||
|
$config = array_filter($config);
|
||||||
|
$uri = implode($config, ',');
|
||||||
|
$uri .= "\r\n";
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
}
|
46
app/Utils/Surge.php
Normal file
46
app/Utils/Surge.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
|
||||||
|
class Surge
|
||||||
|
{
|
||||||
|
public static function buildVmess($uuid, $server)
|
||||||
|
{
|
||||||
|
$proxies = $server->name . ' = vmess, ' . $server->host . ', ' . $server->port . ', username=' . $uuid . ', tfo=true';
|
||||||
|
if ($server->tls) {
|
||||||
|
$tlsSettings = json_decode($server->tlsSettings);
|
||||||
|
$proxies .= ', tls=' . ($server->tls ? "true" : "false");
|
||||||
|
if (isset($tlsSettings->allowInsecure)) {
|
||||||
|
$proxies .= ', skip-cert-verify=' . ($tlsSettings->allowInsecure ? "true" : "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($server->network == 'ws') {
|
||||||
|
$proxies .= ', ws=true';
|
||||||
|
if ($server->networkSettings) {
|
||||||
|
$wsSettings = json_decode($server->networkSettings);
|
||||||
|
if (isset($wsSettings->path)) $proxies .= ', ws-path=' . $wsSettings->path;
|
||||||
|
if (isset($wsSettings->headers->Host)) $proxies .= ', ws-headers=host:' . $wsSettings->headers->Host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$proxies .= "\r\n";
|
||||||
|
return $proxies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function buildTrojan($password, $server)
|
||||||
|
{
|
||||||
|
$config = [
|
||||||
|
"{$server->name}=trojan",
|
||||||
|
"{$server->host}",
|
||||||
|
"{$server->port}",
|
||||||
|
"password={$password}",
|
||||||
|
$server->allow_insecure ? 'skip-cert-verify=true' : 'skip-cert-verify=false',
|
||||||
|
$server->server_name ? "sni={$server->server_name}" : "",
|
||||||
|
"tfo=true"
|
||||||
|
];
|
||||||
|
$config = array_filter($config);
|
||||||
|
$uri = implode($config, ',');
|
||||||
|
$uri .= "\r\n";
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
"laravel/tinker": "^1.0",
|
"laravel/tinker": "^1.0",
|
||||||
"lokielse/omnipay-alipay": "3.0.6",
|
"lokielse/omnipay-alipay": "3.0.6",
|
||||||
"php-curl-class/php-curl-class": "^8.6",
|
"php-curl-class/php-curl-class": "^8.6",
|
||||||
"stripe/stripe-php": "^7.5",
|
"stripe/stripe-php": "^7.36.1",
|
||||||
"symfony/yaml": "^4.3"
|
"symfony/yaml": "^4.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
@ -236,5 +236,5 @@ return [
|
|||||||
| The only modification by laravel config
|
| The only modification by laravel config
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'version' => '1.3'
|
'version' => '1.3.1-r.1'
|
||||||
];
|
];
|
||||||
|
@ -27,6 +27,7 @@ CREATE TABLE `v2_coupon` (
|
|||||||
`type` tinyint(1) NOT NULL,
|
`type` tinyint(1) NOT NULL,
|
||||||
`value` int(11) NOT NULL,
|
`value` int(11) NOT NULL,
|
||||||
`limit_use` int(11) DEFAULT NULL,
|
`limit_use` int(11) DEFAULT NULL,
|
||||||
|
`limit_plan_ids` varchar(255) DEFAULT NULL,
|
||||||
`started_at` int(11) NOT NULL,
|
`started_at` int(11) NOT NULL,
|
||||||
`ended_at` int(11) NOT NULL,
|
`ended_at` int(11) NOT NULL,
|
||||||
`created_at` int(11) NOT NULL,
|
`created_at` int(11) NOT NULL,
|
||||||
@ -165,6 +166,7 @@ CREATE TABLE `v2_server_log` (
|
|||||||
`u` varchar(255) NOT NULL,
|
`u` varchar(255) NOT NULL,
|
||||||
`d` varchar(255) NOT NULL,
|
`d` varchar(255) NOT NULL,
|
||||||
`rate` decimal(10,2) NOT NULL,
|
`rate` decimal(10,2) NOT NULL,
|
||||||
|
`method` varchar(255) NOT NULL,
|
||||||
`log_at` int(11) NOT NULL,
|
`log_at` int(11) NOT NULL,
|
||||||
`created_at` int(11) NOT NULL,
|
`created_at` int(11) NOT NULL,
|
||||||
`updated_at` int(11) NOT NULL,
|
`updated_at` int(11) NOT NULL,
|
||||||
@ -178,11 +180,33 @@ CREATE TABLE `v2_server_stat` (
|
|||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
`server_id` int(11) NOT NULL,
|
`server_id` int(11) NOT NULL,
|
||||||
`u` varchar(255) NOT NULL,
|
`u` varchar(255) NOT NULL,
|
||||||
`d` varchar(25) NOT NULL,
|
`d` varchar(255) NOT NULL,
|
||||||
|
`created_at` int(11) NOT NULL,
|
||||||
|
`updated_at` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `created_at` (`created_at`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `v2_server_trojan`;
|
||||||
|
CREATE TABLE `v2_server_trojan` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '节点ID',
|
||||||
|
`group_id` varchar(255) NOT NULL COMMENT '节点组',
|
||||||
|
`parent_id` int(11) DEFAULT NULL COMMENT '父节点',
|
||||||
|
`tags` varchar(255) DEFAULT NULL COMMENT '节点标签',
|
||||||
|
`name` varchar(255) NOT NULL COMMENT '节点名称',
|
||||||
|
`rate` varchar(11) NOT NULL COMMENT '倍率',
|
||||||
|
`host` varchar(255) NOT NULL COMMENT '主机名',
|
||||||
|
`port` int(11) NOT NULL COMMENT '连接端口',
|
||||||
|
`server_port` int(11) NOT NULL COMMENT '服务端口',
|
||||||
|
`allow_insecure` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否允许不安全',
|
||||||
|
`server_name` varchar(255) DEFAULT NULL,
|
||||||
|
`show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否显示',
|
||||||
|
`sort` int(11) DEFAULT NULL,
|
||||||
`created_at` int(11) NOT NULL,
|
`created_at` int(11) NOT NULL,
|
||||||
`updated_at` int(11) NOT NULL,
|
`updated_at` int(11) NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='trojan伺服器表';
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `v2_ticket`;
|
DROP TABLE IF EXISTS `v2_ticket`;
|
||||||
@ -241,11 +265,12 @@ CREATE TABLE `v2_user` (
|
|||||||
`u` bigint(20) NOT NULL DEFAULT '0',
|
`u` bigint(20) NOT NULL DEFAULT '0',
|
||||||
`d` bigint(20) NOT NULL DEFAULT '0',
|
`d` bigint(20) NOT NULL DEFAULT '0',
|
||||||
`transfer_enable` bigint(20) NOT NULL DEFAULT '0',
|
`transfer_enable` bigint(20) NOT NULL DEFAULT '0',
|
||||||
|
`enable` tinyint(1) NOT NULL DEFAULT '1',
|
||||||
`banned` tinyint(1) NOT NULL DEFAULT '0',
|
`banned` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
`is_admin` tinyint(1) NOT NULL DEFAULT '0',
|
`is_admin` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
`last_login_at` int(11) DEFAULT NULL,
|
`last_login_at` int(11) DEFAULT NULL,
|
||||||
`last_login_ip` int(11) DEFAULT NULL,
|
`last_login_ip` int(11) DEFAULT NULL,
|
||||||
`v2ray_uuid` varchar(36) NOT NULL,
|
`uuid` varchar(36) NOT NULL,
|
||||||
`v2ray_alter_id` tinyint(4) NOT NULL DEFAULT '2',
|
`v2ray_alter_id` tinyint(4) NOT NULL DEFAULT '2',
|
||||||
`v2ray_level` tinyint(4) NOT NULL DEFAULT '0',
|
`v2ray_level` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
`group_id` int(11) DEFAULT NULL,
|
`group_id` int(11) DEFAULT NULL,
|
||||||
@ -261,4 +286,4 @@ CREATE TABLE `v2_user` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
-- 2020-05-12 12:31:04
|
-- 2020-07-01 07:01:59
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateUsersTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('users', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->string('name');
|
|
||||||
$table->string('email')->unique();
|
|
||||||
$table->timestamp('email_verified_at')->nullable();
|
|
||||||
$table->string('password');
|
|
||||||
$table->rememberToken();
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('users');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreatePasswordResetsTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('password_resets', function (Blueprint $table) {
|
|
||||||
$table->string('email')->index();
|
|
||||||
$table->string('token');
|
|
||||||
$table->timestamp('created_at')->nullable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('password_resets');
|
|
||||||
}
|
|
||||||
}
|
|
@ -118,14 +118,6 @@ CREATE TABLE `v2_tutorial` (
|
|||||||
`updated_at` int(11) NOT NULL
|
`updated_at` int(11) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
|
||||||
|
|
||||||
INSERT INTO `v2_tutorial` (`id`, `title`, `description`, `icon`, `steps`, `show`, `created_at`, `updated_at`) VALUES
|
|
||||||
(1, 'Windows', '兼容 Windows 7 以上的版本', 'fab fa-2x fa-windows', '[{\"default_area\":\"<div><div>下载 V2rayN 客户端。</div><div>下载完成后解压,解压完成后运行V2rayN</div><div>运行时请右键,以管理员身份运行</div></div>\",\"download_url\":\"/downloads/V2rayN.zip\"},{\"default_area\":\"<div>点击订阅按钮,选择订阅设置点击添加,输入如下内容后点击确定保存</div>\",\"safe_area\":\"<div>备注:<code onclick=\\\"safeAreaCopy(\'{{$app_name}}\')\\\">{{$app_name}}</code></div>\\n<div>地址(url):<code onclick=\\\"safeAreaCopy(\'{{$subscribe_url}}\')\\\">{{$subscribe_url}}</code></div>\",\"img_url\":\"https://i.loli.net/2019/11/21/UkcHNtERTnjLVS8.jpg\"},{\"default_area\":\"<div>点击订阅后,从服务器列表选择服务器</div>\",\"img_url\":\"https://i.loli.net/2019/11/21/BgPGFQ3kCSuIRjJ.jpg\"},{\"default_area\":\"<div>点击参数设置,找到Http代理,选择PAC模式后按确定保存即启动代理。</div>\",\"img_url\":\"https://i.loli.net/2019/11/21/vnVykKEFT8Lzo3f.jpg\"}]', 1, 1577972408, 1577980882),
|
|
||||||
(2, 'Android', '兼容 Android 6 以上的版本', 'fab fa-2x fa-android', '[{\"default_area\":\"<div>下载 V2rayNG 客户端。</div>\",\"safe_area\":\"\",\"download_url\":\"/downloads/V2rayNG.apk\"},{\"default_area\":\"<div>打开 V2rayNG 点击左上角的菜单图标打开侧边栏,随后点击 订阅设置,点击右上角的➕按钮新增订阅。</div><div>按照下方内容进行填写,填写完毕后点击右上角的☑️按钮。</div>\",\"safe_area\":\"<div>备注:<code onclick=\\\"safeAreaCopy(\'{{$app_name}}\')\\\">{{$app_name}}</code></div>\\n<div>地址(url):<code onclick=\\\"safeAreaCopy(\'{{$subscribe_url}}\')\\\">{{$subscribe_url}}</code></div>\",\"download_url\":\"\",\"img_url\":\"https://i.loli.net/2019/11/21/ghuVkTe6LBqRxSO.jpg\"},{\"default_area\":\"<div>再次从侧边栏进入 设置 页面,点击 路由模式 将其更改为 \\b绕过局域网及大陆地址。</div>\",\"img_url\":\"https://i.loli.net/2019/11/21/Tf1AGoXZuhJrwOq.jpg\"},{\"default_area\":\"<div>随后从侧边栏回到 配置文件 页面,点击右上角的省略号图标选择更新订阅。</div>\",\"img_url\":\"https://i.loli.net/2019/11/21/UtfPShQXupRmB4L.jpg\"},{\"img_url\":\"https://i.loli.net/2019/11/21/ZkbNsSrAg3m5Dny.jpg\",\"default_area\":\"<div>点击选择您需要的节点,点击右下角的V字按钮即可连接。</div>\"}]', 1, 1577972534, 1577981610),
|
|
||||||
(3, 'macOS', '兼容 Yosemite 以上的版本', 'fab fa-2x fa-apple', '[{\"default_area\":\"<div>下载 ClashX 客户端,安装后运行。</div>\",\"download_url\":\"/downloads/ClashX.dmg\",\"img_url\":\"https://i.loli.net/2019/11/20/uNGrjl2noCL1f5B.jpg\"},{\"default_area\":\"<div>点击通知栏 ClashX 图标保持选中状态,按快捷键 ⌘+M(订阅快捷键),在弹出的窗口点击添加输入下方信息</div>\",\"safe_area\":\"<div>Url:<code onclick=\\\"safeAreaCopy(\'{{$subscribe_url}}\')\\\">{{$subscribe_url}}</code></div>\\n<div>Config Name:<code onclick=\\\"safeAreaCopy(\'{{$app_name}}\')\\\">{{$app_name}}</code></div>\",\"img_url\":\"https://i.loli.net/2019/11/20/8eB13mRbFuszwxg.jpg\"},{\"default_area\":\"<div>点击通知栏 ClashX 图标保持选中状态,按快捷键 ⌘+S(设置为系统代理快捷键),即连接完成</div>\"}]', 1, 1577979855, 1577981646),
|
|
||||||
(4, 'iOS', '兼容 iOS 9 以上的版本', 'fab fa-2x fa-apple', '[{\"default_area\":\"<div>iOS上使用请在iOS浏览器中打开本页</div>\"},{\"default_area\":\"<div>在 App Store 登录本站提供的美区 Apple ID 下载客户端。</div><div>为了保护您的隐私,请勿在手机设置里直接登录,仅在 App Store 登录即可。</div><div>登陆完成后点击下方下载会自动唤起下载。</div>\",\"safe_area\":\"<div>Apple ID:<code onclick=\\\"safeAreaCopy(\'{{$apple_id}}\')\\\">{{$apple_id}}</code></div><div>密码:<code onclick=\\\"safeAreaCopy(\'{{$apple_id_password}}\')\\\">点击复制密码</code></div>\",\"download_url\":\"https://apps.apple.com/us/app/shadowrocket/id932747118\",\"img_url\":\"https://i.loli.net/2019/11/21/5idkjJ61stWgREV.jpg\"},{\"default_area\":\"<div>待客户端安装完成后,点击下方一键订阅按钮会自动唤起并进行订阅</div>\",\"safe_area\":\"\",\"img_url\":\"https://i.loli.net/2019/11/21/ZcqlNMb3eg5Uhxd.jpg\",\"download_url\":\"shadowrocket://add/sub://{{$b64_subscribe_url}}?remark={{$app_name}}\"},{\"default_area\":\"<div>选择节点进行链接,首次链接过程授权窗口请一路允许。</div>\",\"img_url\":\"https://i.loli.net/2019/11/21/9Zdxksr7Ey6hjlm.jpg\"}]', 1, 1577982016, 1577983283);
|
|
||||||
|
|
||||||
ALTER TABLE `v2_server_log`
|
ALTER TABLE `v2_server_log`
|
||||||
CHANGE `rate` `rate` decimal(10,2) NOT NULL AFTER `d`;
|
CHANGE `rate` `rate` decimal(10,2) NOT NULL AFTER `d`;
|
||||||
|
|
||||||
@ -256,3 +248,51 @@ ADD INDEX log_at (`log_at`);
|
|||||||
|
|
||||||
ALTER TABLE `v2_user`
|
ALTER TABLE `v2_user`
|
||||||
ADD `telegram_id` bigint NULL AFTER `invite_user_id`;
|
ADD `telegram_id` bigint NULL AFTER `invite_user_id`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_stat`
|
||||||
|
ADD `online` int(11) NOT NULL AFTER `d`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_stat`
|
||||||
|
ADD INDEX `created_at` (`created_at`);
|
||||||
|
|
||||||
|
CREATE TABLE `v2_server_trojan` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`group_id` varchar(255) NOT NULL,
|
||||||
|
`tags` varchar(255) NULL,
|
||||||
|
`name` varchar(255) NOT NULL,
|
||||||
|
`host` varchar(255) NOT NULL,
|
||||||
|
`port` int(11) NOT NULL,
|
||||||
|
`show` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
|
`sort` int(11) NULL,
|
||||||
|
`created_at` int(11) NOT NULL,
|
||||||
|
`updated_at` int(11) NOT NULL
|
||||||
|
) COMMENT='trojan伺服器表' COLLATE 'utf8mb4_general_ci';
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_stat`
|
||||||
|
CHANGE `d` `d` varchar(255) COLLATE 'utf8_general_ci' NOT NULL AFTER `u`,
|
||||||
|
DROP `online`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_user`
|
||||||
|
CHANGE `v2ray_uuid` `uuid` varchar(36) COLLATE 'utf8_general_ci' NOT NULL AFTER `last_login_ip`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_trojan`
|
||||||
|
ADD `rate` varchar(11) COLLATE 'utf8mb4_general_ci' NOT NULL AFTER `name`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_log`
|
||||||
|
ADD `method` varchar(255) NOT NULL AFTER `rate`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_coupon`
|
||||||
|
ADD `limit_plan_ids` varchar(255) NULL AFTER `limit_use`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_trojan`
|
||||||
|
ADD `server_port` int(11) NOT NULL AFTER `port`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_trojan`
|
||||||
|
ADD `parent_id` int(11) NULL AFTER `group_id`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_trojan`
|
||||||
|
ADD `allow_insecure` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否允许不安全' AFTER `server_port`,
|
||||||
|
CHANGE `show` `show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否显示' AFTER `allow_insecure`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server_trojan`
|
||||||
|
ADD `server_name` varchar(255) NULL AFTER `allow_insecure`;
|
||||||
|
@ -23,6 +23,9 @@ class PayTaro
|
|||||||
$curl = new Curl();
|
$curl = new Curl();
|
||||||
$curl->post('https://api.paytaro.com/v1/gateway/fetch', http_build_query($params));
|
$curl->post('https://api.paytaro.com/v1/gateway/fetch', http_build_query($params));
|
||||||
$result = $curl->response;
|
$result = $curl->response;
|
||||||
|
if (!$result) {
|
||||||
|
abort(500, '网络异常');
|
||||||
|
}
|
||||||
if ($curl->error) {
|
if ($curl->error) {
|
||||||
$errors = (array)$result->errors;
|
$errors = (array)$result->errors;
|
||||||
abort(500, $errors[array_keys($errors)[0]][0]);
|
abort(500, $errors[array_keys($errors)[0]][0]);
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Library;
|
|
||||||
|
|
||||||
class TomatoPay
|
|
||||||
{
|
|
||||||
private $mchid;
|
|
||||||
private $account;
|
|
||||||
private $key;
|
|
||||||
|
|
||||||
public function __construct($mchid, $account, $key)
|
|
||||||
{
|
|
||||||
$this->mchid = $mchid;
|
|
||||||
$this->account = $account;
|
|
||||||
$this->key = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function alipay($cny, $trade)
|
|
||||||
{
|
|
||||||
$params = [
|
|
||||||
'mchid' => $this->mchid,
|
|
||||||
'account' => $this->account,
|
|
||||||
'cny' => $cny,
|
|
||||||
'type' => '1',
|
|
||||||
'trade' => $trade
|
|
||||||
];
|
|
||||||
$params['signs'] = $this->sign($params);
|
|
||||||
return $this->buildHtml('https://b.fanqieui.com/gateways/alipay.php', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function wxpay($cny, $trade)
|
|
||||||
{
|
|
||||||
$params = [
|
|
||||||
'mchid' => $this->mchid,
|
|
||||||
'account' => $this->account,
|
|
||||||
'cny' => $cny,
|
|
||||||
'type' => '1',
|
|
||||||
'trade' => $trade
|
|
||||||
];
|
|
||||||
$params['signs'] = $this->sign($params);
|
|
||||||
return $this->buildHtml('https://b.fanqieui.com/gateways/wxpay.php', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sign($params)
|
|
||||||
{
|
|
||||||
$o = '';
|
|
||||||
foreach ($params as $k => $v) {
|
|
||||||
$o .= "$k=" . ($v) . "&";
|
|
||||||
}
|
|
||||||
return md5(substr($o, 0, -1) . $this->key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildHtml($url, $params, $method = 'post', $target = '_self')
|
|
||||||
{
|
|
||||||
// return var_dump($params);
|
|
||||||
$html = "<form id='submit' name='submit' action='" . $url . "' method='$method' target='$target'>";
|
|
||||||
foreach ($params as $key => $value) {
|
|
||||||
$html .= "<input type='hidden' name='$key' value='$value'/>";
|
|
||||||
}
|
|
||||||
$html .= "</form><script>document.forms['submit'].submit();</script>";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
}
|
|
14
library/V2ray.php
Normal file
14
library/V2ray.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Library;
|
||||||
|
|
||||||
|
|
||||||
|
class V2ray
|
||||||
|
{
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->config = new \StdClass();
|
||||||
|
}
|
||||||
|
}
|
2
public/assets/admin/umi.css
vendored
2
public/assets/admin/umi.css
vendored
File diff suppressed because one or more lines are too long
2
public/assets/admin/umi.js
vendored
2
public/assets/admin/umi.js
vendored
File diff suppressed because one or more lines are too long
2
public/assets/user/umi.css
vendored
2
public/assets/user/umi.css
vendored
File diff suppressed because one or more lines are too long
2
public/assets/user/umi.js
vendored
2
public/assets/user/umi.js
vendored
File diff suppressed because one or more lines are too long
524
resources/rules/app.clash.yaml
Normal file
524
resources/rules/app.clash.yaml
Normal file
@ -0,0 +1,524 @@
|
|||||||
|
port: 8890
|
||||||
|
socks-port: 8891
|
||||||
|
allow-lan: false
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: 127.0.0.1:9091
|
||||||
|
experimental:
|
||||||
|
ignore-resolve-fail: true
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: false
|
||||||
|
enhanced-mode: redir-host
|
||||||
|
nameserver:
|
||||||
|
- 1.2.4.8
|
||||||
|
- 223.5.5.5
|
||||||
|
fallback:
|
||||||
|
- tls://1.0.0.1:853
|
||||||
|
- tls://dns.google:853
|
||||||
|
proxies:
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
- { name: "SELECT", type: select, proxies: ["自动选择", "故障转移"] }
|
||||||
|
- { name: "自动选择", type: url-test, proxies: [], url: "http://www.gstatic.com/generate_204", interval: 86400 }
|
||||||
|
- { name: "故障转移", type: fallback, proxies: [], url: "http://www.gstatic.com/generate_204", interval: 7200 }
|
||||||
|
|
||||||
|
rules:
|
||||||
|
# Apple
|
||||||
|
- DOMAIN,safebrowsing.urlsec.qq.com,DIRECT # 如果您并不信任此服务提供商或防止其下载消耗过多带宽资源,可以进入 Safari 设置,关闭 Fraudulent Website Warning 功能,并使用 REJECT 策略。
|
||||||
|
- DOMAIN,safebrowsing.googleapis.com,DIRECT # 如果您并不信任此服务提供商或防止其下载消耗过多带宽资源,可以进入 Safari 设置,关闭 Fraudulent Website Warning 功能,并使用 REJECT 策略。
|
||||||
|
- DOMAIN,ocsp.apple.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,digicert.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,entrust.net,SELECT
|
||||||
|
- DOMAIN,ocsp.verisign.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,apps.apple.com,SELECT
|
||||||
|
- DOMAIN,itunes.apple.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blobstore.apple.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,music.apple.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,mzstatic.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,itunes.apple.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,icloud.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,icloud-content.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,me.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,mzstatic.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,akadns.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,aaplimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,cdn-apple.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,apple.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,apple-cloudkit.com,DIRECT
|
||||||
|
# - DOMAIN,e.crashlytics.com,REJECT //注释此选项有助于大多数App开发者分析崩溃信息;如果您拒绝一切崩溃数据统计、搜集,请取消 # 注释。
|
||||||
|
|
||||||
|
|
||||||
|
# 自定义规则
|
||||||
|
## 您可以在此处插入您补充的自定义规则(请注意保持缩进)
|
||||||
|
|
||||||
|
# 国内网站
|
||||||
|
- DOMAIN-SUFFIX,cn,DIRECT
|
||||||
|
- DOMAIN-KEYWORD,-cn,DIRECT
|
||||||
|
|
||||||
|
- DOMAIN-SUFFIX,126.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,126.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,127.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,163.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,360buyimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,36kr.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,acfun.tv,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,air-matters.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,aixifan.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,akamaized.net,DIRECT
|
||||||
|
- DOMAIN-KEYWORD,alicdn,DIRECT
|
||||||
|
- DOMAIN-KEYWORD,alipay,DIRECT
|
||||||
|
- DOMAIN-KEYWORD,taobao,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,amap.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,autonavi.com,DIRECT
|
||||||
|
- DOMAIN-KEYWORD,baidu,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,bdimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,bdstatic.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,bilibili.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,bilivideo.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,caiyunapp.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,clouddn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,cnbeta.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,cnbetacdn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,cootekservice.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,csdn.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ctrip.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,dgtle.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,dianping.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,douban.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,doubanio.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,duokan.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,easou.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ele.me,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,feng.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,fir.im,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,frdic.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,g-cores.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,godic.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,gtimg.com,DIRECT
|
||||||
|
- DOMAIN,cdn.hockeyapp.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,hdslb.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,hongxiu.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,hxcdn.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,iciba.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ifeng.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ifengimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ipip.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,iqiyi.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,jd.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,jianshu.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,knewone.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,le.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,lecloud.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,lemicp.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,licdn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,linkedin.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,luoo.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,meituan.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,meituan.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,mi.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,miaopai.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,microsoft.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,microsoftonline.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,miui.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,miwifi.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,mob.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,netease.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,office.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,office365.com,DIRECT
|
||||||
|
- DOMAIN-KEYWORD,officecdn,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,oschina.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ppsimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,pstatp.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qcloud.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qdaily.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qdmm.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qhimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qhres.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qidian.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qihucdn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qiniu.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qiniucdn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qiyipic.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qq.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,qqurl.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,rarbg.to,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ruguoapp.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,segmentfault.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,sinaapp.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,smzdm.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,snapdrop.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,sogou.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,sogoucdn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,sohu.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,soku.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,speedtest.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,sspai.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,suning.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,taobao.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,tencent.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,tenpay.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,tianyancha.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,tmall.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,tudou.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,umetrip.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,upaiyun.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,upyun.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,veryzhun.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,weather.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,weibo.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,xiami.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,xiami.net,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,xiaomicp.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ximalaya.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,xmcdn.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,xunlei.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,yhd.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,yihaodianimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,yinxiang.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,ykimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,youdao.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,youku.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,zealer.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,zhihu.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,zhimg.com,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,zimuzu.tv,DIRECT
|
||||||
|
- DOMAIN-SUFFIX,zoho.com,DIRECT
|
||||||
|
|
||||||
|
# 抗 DNS 污染
|
||||||
|
- DOMAIN-KEYWORD,amazon,SELECT
|
||||||
|
- DOMAIN-KEYWORD,google,SELECT
|
||||||
|
- DOMAIN-KEYWORD,gmail,SELECT
|
||||||
|
- DOMAIN-KEYWORD,youtube,SELECT
|
||||||
|
- DOMAIN-KEYWORD,facebook,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fb.me,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fbcdn.net,SELECT
|
||||||
|
- DOMAIN-KEYWORD,twitter,SELECT
|
||||||
|
- DOMAIN-KEYWORD,instagram,SELECT
|
||||||
|
- DOMAIN-KEYWORD,dropbox,SELECT
|
||||||
|
- DOMAIN-SUFFIX,twimg.com,SELECT
|
||||||
|
- DOMAIN-KEYWORD,blogspot,SELECT
|
||||||
|
- DOMAIN-SUFFIX,youtu.be,SELECT
|
||||||
|
- DOMAIN-KEYWORD,whatsapp,SELECT
|
||||||
|
|
||||||
|
# 常见广告域名屏蔽
|
||||||
|
- DOMAIN-KEYWORD,admarvel,REJECT
|
||||||
|
- DOMAIN-KEYWORD,admaster,REJECT
|
||||||
|
- DOMAIN-KEYWORD,adsage,REJECT
|
||||||
|
- DOMAIN-KEYWORD,adsmogo,REJECT
|
||||||
|
- DOMAIN-KEYWORD,adsrvmedia,REJECT
|
||||||
|
- DOMAIN-KEYWORD,adwords,REJECT
|
||||||
|
- DOMAIN-KEYWORD,adservice,REJECT
|
||||||
|
- DOMAIN-KEYWORD,domob,REJECT
|
||||||
|
- DOMAIN-KEYWORD,duomeng,REJECT
|
||||||
|
- DOMAIN-KEYWORD,dwtrack,REJECT
|
||||||
|
- DOMAIN-KEYWORD,guanggao,REJECT
|
||||||
|
- DOMAIN-KEYWORD,lianmeng,REJECT
|
||||||
|
- DOMAIN-SUFFIX,mmstat.com,REJECT
|
||||||
|
- DOMAIN-KEYWORD,omgmta,REJECT
|
||||||
|
- DOMAIN-KEYWORD,openx,REJECT
|
||||||
|
- DOMAIN-KEYWORD,partnerad,REJECT
|
||||||
|
- DOMAIN-KEYWORD,pingfore,REJECT
|
||||||
|
- DOMAIN-KEYWORD,supersonicads,REJECT
|
||||||
|
- DOMAIN-KEYWORD,tracking,REJECT
|
||||||
|
- DOMAIN-KEYWORD,uedas,REJECT
|
||||||
|
- DOMAIN-KEYWORD,umeng,REJECT
|
||||||
|
- DOMAIN-KEYWORD,usage,REJECT
|
||||||
|
- DOMAIN-KEYWORD,wlmonitor,REJECT
|
||||||
|
- DOMAIN-KEYWORD,zjtoolbar,REJECT
|
||||||
|
|
||||||
|
# 国外网站
|
||||||
|
- DOMAIN-SUFFIX,9to5mac.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,abpchina.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,adblockplus.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,adobe.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,alfredapp.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,amplitude.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ampproject.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,android.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,angularjs.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,aolcdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,apkpure.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,appledaily.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,appshopper.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,appspot.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,arcgis.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,archive.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,armorgames.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,aspnetcdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,att.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,awsstatic.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,azureedge.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,azurewebsites.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bing.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bintray.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bit.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bit.ly,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bitbucket.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bjango.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bkrtx.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blog.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blogcdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blogger.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blogsmithmedia.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blogspot.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,blogspot.hk,SELECT
|
||||||
|
- DOMAIN-SUFFIX,bloomberg.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,box.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,box.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cachefly.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,chromium.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cl.ly,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cloudflare.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cloudfront.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cloudmagic.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cmail19.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cnet.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,cocoapods.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,comodoca.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,crashlytics.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,culturedcode.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,d.pr,SELECT
|
||||||
|
- DOMAIN-SUFFIX,danilo.to,SELECT
|
||||||
|
- DOMAIN-SUFFIX,dayone.me,SELECT
|
||||||
|
- DOMAIN-SUFFIX,db.tt,SELECT
|
||||||
|
- DOMAIN-SUFFIX,deskconnect.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,disq.us,SELECT
|
||||||
|
- DOMAIN-SUFFIX,disqus.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,disquscdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,dnsimple.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,docker.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,dribbble.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,droplr.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,duckduckgo.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,dueapp.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,dytt8.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,edgecastcdn.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,edgekey.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,edgesuite.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,engadget.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,entrust.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,eurekavpt.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,evernote.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fabric.io,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fast.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fastly.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fc2.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,feedburner.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,feedly.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,feedsportal.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,fiftythree.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,firebaseio.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,flexibits.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,flickr.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,flipboard.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,g.co,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gabia.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,geni.us,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gfx.ms,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ggpht.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ghostnoteapp.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,git.io,SELECT
|
||||||
|
- DOMAIN-KEYWORD,github,SELECT
|
||||||
|
- DOMAIN-SUFFIX,globalsign.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gmodules.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,godaddy.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,golang.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gongm.in,SELECT
|
||||||
|
- DOMAIN-SUFFIX,goo.gl,SELECT
|
||||||
|
- DOMAIN-SUFFIX,goodreaders.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,goodreads.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gravatar.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gstatic.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,gvt0.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,hockeyapp.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,hotmail.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,icons8.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ifixit.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ift.tt,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ifttt.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,iherb.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,imageshack.us,SELECT
|
||||||
|
- DOMAIN-SUFFIX,img.ly,SELECT
|
||||||
|
- DOMAIN-SUFFIX,imgur.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,imore.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,instapaper.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ipn.li,SELECT
|
||||||
|
- DOMAIN-SUFFIX,is.gd,SELECT
|
||||||
|
- DOMAIN-SUFFIX,issuu.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,itgonglun.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,itun.es,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ixquick.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,j.mp,SELECT
|
||||||
|
- DOMAIN-SUFFIX,js.revsci.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,jshint.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,jtvnw.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,justgetflux.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,kat.cr,SELECT
|
||||||
|
- DOMAIN-SUFFIX,klip.me,SELECT
|
||||||
|
- DOMAIN-SUFFIX,libsyn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,linode.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,lithium.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,littlehj.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,live.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,live.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,livefilestore.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,llnwd.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,macid.co,SELECT
|
||||||
|
- DOMAIN-SUFFIX,macromedia.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,macrumors.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,mashable.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,mathjax.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,medium.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,mega.co.nz,SELECT
|
||||||
|
- DOMAIN-SUFFIX,mega.nz,SELECT
|
||||||
|
- DOMAIN-SUFFIX,megaupload.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,microsofttranslator.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,mindnode.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,mobile01.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,modmyi.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,msedge.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,myfontastic.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,name.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,nextmedia.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,nsstatic.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,nssurge.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,nyt.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,nytimes.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,omnigroup.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,onedrive.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,onenote.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ooyala.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,openvpn.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,openwrt.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,orkut.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,osxdaily.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,outlook.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ow.ly,SELECT
|
||||||
|
- DOMAIN-SUFFIX,paddleapi.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,parallels.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,parse.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,pdfexpert.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,periscope.tv,SELECT
|
||||||
|
- DOMAIN-SUFFIX,pinboard.in,SELECT
|
||||||
|
- DOMAIN-SUFFIX,pinterest.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,pixelmator.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,pixiv.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,playpcesor.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,playstation.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,playstation.com.hk,SELECT
|
||||||
|
- DOMAIN-SUFFIX,playstation.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,playstationnetwork.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,pushwoosh.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,rime.im,SELECT
|
||||||
|
- DOMAIN-SUFFIX,servebom.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,sfx.ms,SELECT
|
||||||
|
- DOMAIN-SUFFIX,shadowsocks.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,sharethis.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,shazam.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,skype.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,smartdnsSELECT.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,smartmailcloud.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,sndcdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,sony.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,soundcloud.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,sourceforge.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,spotify.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,squarespace.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,sstatic.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,st.luluku.pw,SELECT
|
||||||
|
- DOMAIN-SUFFIX,stackoverflow.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,startpage.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,staticflickr.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,steamcommunity.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,symauth.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,symcb.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,symcd.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tapbots.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tapbots.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tdesktop.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,techcrunch.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,techsmith.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,thepiratebay.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,theverge.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,time.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,timeinc.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tiny.cc,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tinypic.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tmblr.co,SELECT
|
||||||
|
- DOMAIN-SUFFIX,todoist.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,trello.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,trustasiassl.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tumblr.co,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tumblr.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tweetdeck.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,tweetmarker.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,twitch.tv,SELECT
|
||||||
|
- DOMAIN-SUFFIX,txmblr.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,typekit.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ubertags.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ublock.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ubnt.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ulyssesapp.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,urchin.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,usertrust.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,v.gd,SELECT
|
||||||
|
- DOMAIN-SUFFIX,v2ex.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vimeo.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vimeocdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vine.co,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vivaldi.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vox-cdn.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vsco.co,SELECT
|
||||||
|
- DOMAIN-SUFFIX,vultr.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,w.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,w3schools.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,webtype.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wikiwand.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wikileaks.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wikimedia.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wikipedia.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wikipedia.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,windows.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,windows.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wire.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wordpress.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,workflowy.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wp.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wsj.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,wsj.net,SELECT
|
||||||
|
- DOMAIN-SUFFIX,xda-developers.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,xeeno.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,xiti.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,yahoo.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,yimg.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ying.com,SELECT
|
||||||
|
- DOMAIN-SUFFIX,yoyo.org,SELECT
|
||||||
|
- DOMAIN-SUFFIX,ytimg.com,SELECT
|
||||||
|
|
||||||
|
# Telegram
|
||||||
|
- DOMAIN-SUFFIX,telegra.ph,SELECT
|
||||||
|
- DOMAIN-SUFFIX,telegram.org,SELECT
|
||||||
|
|
||||||
|
- IP-CIDR,91.108.4.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,91.108.8.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,91.108.12.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,91.108.16.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,91.108.56.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,149.154.160.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,149.154.164.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,149.154.168.0/22,SELECT,no-resolve
|
||||||
|
- IP-CIDR,149.154.172.0/22,SELECT,no-resolve
|
||||||
|
|
||||||
|
# LAN
|
||||||
|
- DOMAIN-SUFFIX,local,DIRECT
|
||||||
|
- IP-CIDR,127.0.0.0/8,DIRECT
|
||||||
|
- IP-CIDR,172.16.0.0/12,DIRECT
|
||||||
|
- IP-CIDR,192.168.0.0/16,DIRECT
|
||||||
|
- IP-CIDR,10.0.0.0/8,DIRECT
|
||||||
|
- IP-CIDR,17.0.0.0/8,DIRECT
|
||||||
|
- IP-CIDR,100.64.0.0/10,DIRECT
|
||||||
|
|
||||||
|
# 最终规则
|
||||||
|
- GEOIP,CN,DIRECT
|
||||||
|
- MATCH,SELECT
|
@ -1,7 +1,7 @@
|
|||||||
port: 7890
|
port: 7890
|
||||||
socks-port: 7891
|
socks-port: 7891
|
||||||
allow-lan: false
|
allow-lan: false
|
||||||
mode: Rule
|
mode: rule
|
||||||
log-level: info
|
log-level: info
|
||||||
external-controller: 127.0.0.1:9090
|
external-controller: 127.0.0.1:9090
|
||||||
experimental:
|
experimental:
|
||||||
@ -16,14 +16,14 @@ dns:
|
|||||||
fallback:
|
fallback:
|
||||||
- tls://1.0.0.1:853
|
- tls://1.0.0.1:853
|
||||||
- tls://dns.google:853
|
- tls://dns.google:853
|
||||||
Proxy:
|
proxies:
|
||||||
|
|
||||||
Proxy Group:
|
proxy-groups:
|
||||||
- { name: "$app_name", type: select, proxies: ["自动选择", "故障转移"] }
|
- { name: "$app_name", type: select, proxies: ["自动选择", "故障转移"] }
|
||||||
- { name: "自动选择", type: url-test, proxies: [], url: "http://www.gstatic.com/generate_204", interval: 86400 }
|
- { name: "自动选择", type: url-test, proxies: [], url: "http://www.gstatic.com/generate_204", interval: 86400 }
|
||||||
- { name: "故障转移", type: fallback, proxies: [], url: "http://www.gstatic.com/generate_204", interval: 7200 }
|
- { name: "故障转移", type: fallback, proxies: [], url: "http://www.gstatic.com/generate_204", interval: 7200 }
|
||||||
|
|
||||||
Rule:
|
rules:
|
||||||
# Apple
|
# Apple
|
||||||
- DOMAIN,safebrowsing.urlsec.qq.com,DIRECT # 如果您并不信任此服务提供商或防止其下载消耗过多带宽资源,可以进入 Safari 设置,关闭 Fraudulent Website Warning 功能,并使用 REJECT 策略。
|
- DOMAIN,safebrowsing.urlsec.qq.com,DIRECT # 如果您并不信任此服务提供商或防止其下载消耗过多带宽资源,可以进入 Safari 设置,关闭 Fraudulent Website Warning 功能,并使用 REJECT 策略。
|
||||||
- DOMAIN,safebrowsing.googleapis.com,DIRECT # 如果您并不信任此服务提供商或防止其下载消耗过多带宽资源,可以进入 Safari 设置,关闭 Fraudulent Website Warning 功能,并使用 REJECT 策略。
|
- DOMAIN,safebrowsing.googleapis.com,DIRECT # 如果您并不信任此服务提供商或防止其下载消耗过多带宽资源,可以进入 Safari 设置,关闭 Fraudulent Website Warning 功能,并使用 REJECT 策略。
|
||||||
|
@ -13,7 +13,7 @@ http-listen = 0.0.0.0:6152
|
|||||||
socks5-listen = 0.0.0.0:6153
|
socks5-listen = 0.0.0.0:6153
|
||||||
|
|
||||||
test-timeout = 4
|
test-timeout = 4
|
||||||
network-framework = true
|
network-framework = false
|
||||||
proxy-test-url = http://www.gstatic.com/generate_204
|
proxy-test-url = http://www.gstatic.com/generate_204
|
||||||
|
|
||||||
external-controller-access = surgepasswd@0.0.0.0:6170
|
external-controller-access = surgepasswd@0.0.0.0:6170
|
||||||
|
Loading…
Reference in New Issue
Block a user