Update On Sun Oct 5 20:34:08 CEST 2025

This commit is contained in:
github-action[bot]
2025-10-05 20:34:09 +02:00
parent cadd2d0091
commit ef8c467680
346 changed files with 23370 additions and 13811 deletions

View File

@@ -17,6 +17,12 @@
:placeholder="$t('subscription.remarks')"
/>
</b-field>
<b-field label="AUTO-SELECT">
<b-checkbox
v-model="which.autoSelect"
>{{ $t("subscription.autoSelect") }}
</b-checkbox>
</b-field>
</section>
<footer class="modal-card-foot flex-end">
<button class="button" type="button" @click="$parent.close()">

View File

@@ -60,6 +60,7 @@ export default {
timeLastUpdate: "Datetime of Last Update",
numberServers: "Number of Servers",
subscription: "Subscription",
autoSelect: "Automatically connect to new servers from the subscription after an automatic update of the subscription",
},
operations: {
name: "Operations",

View File

@@ -60,6 +60,7 @@ export default {
timeLastUpdate: "Время последнего обновления",
numberServers: "Число серверов",
subscription: "Подписка",
autoSelect: "Автоматически подключаться к новым серверам после автоматичкского обновления подписки",
},
operations: {
name: "Операции",
@@ -88,6 +89,7 @@ export default {
no: "Нет",
switchSite: "Переключится в альтернативный сайт",
addOutbound: "Добавить исходящий узел",
domainsExcluded: "Исключённые домены"
},
register: {
title: "Создайте учётную запись администратора",
@@ -115,6 +117,7 @@ export default {
ipForwardOn: "IP форвардинг",
portSharingOn: "Port Sharing",
concurrency: "Параллелизм",
inboundSniffing: "Сниффер",
options: {
global: "Не разделять трафик",
direct: "Напрямую",
@@ -140,6 +143,7 @@ export default {
leastPing: "С наименьшей задержкой",
},
messages: {
inboundSniffing: "Анализировать входящий трафик. Если эта опция выключена, часть трафик может быть не перенаправлена корректно.",
gfwlist:
"Основывается на времени изменения файла, которое иногда бывает после последней версии в Интернете.",
transparentProxy:
@@ -156,7 +160,7 @@ export default {
"Упростить процесс TCP рукопожатия для ускорения установки соединения. Есть риск распознавания характеристик пакетов. Это может помешать установить соединение если ваша система не подергивает это",
mux:
"Мультиплексировать TCP соединения чтобы снизить количество рукопожатий, но это влияет на варианты использования с высоким трафиком, такие как просмотр видео, скачивание, и проверка скорости. " +
"Есть риск распознавания характеристик пакетов. Подергивается только в vmess.",
"Есть риск распознавания характеристик пакетов. Поддерживается только в vmess.",
confirmEgressPorts: `<p>Вы настраиваете прозрачный прокси-сервер между локальными сетями, подтвердите белый список портов на выходе.</p>
<p>Белый список:</p>
<p>TCP: {tcpPorts}</p>
@@ -321,4 +325,12 @@ export default {
seconds: "секунд",
autoScoll: "Авто-пролистывание",
},
domainsExcluded: {
title: "Исключённые домены",
messages: [
"Список доменных имён. Если анализатор трафика обнаруживает доменное имя из списка, адрес назначения не будет сбрасываться."
],
formName: "Список исключённых доменов",
formPlaceholder: "courier.push.apple.com\nMijia Cloud\ndlg.io.mi.com"
},
};

View File

@@ -1,52 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
M8GH
=ZFOL
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
7hoNkcANGouz3QH37bM7CcMCu7pzVAC92C4=
=C2eB
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -19,6 +19,7 @@ type Params struct {
Config string `id:"config" short:"c" desc:"v2rayA configuration directory"`
V2rayConfigDirectory string `id:"v2ray-confdir" desc:"Additional v2ray config directory, files in it will be combined with config generated by v2rayA"`
V2rayAssetsDirectory string `id:"v2ray-assetsdir" desc:"v2ray-core assets directory for searching and downloading files like geoip.dat. This will override environment V2RAY_LOCATION_ASSET and XRAY_LOCATION_ASSET."`
CoreStartupTimeout int64 `id:"core-startup-timeout" default:"15" desc:"Timeout duration in seconds for starting v2ray or xray core. On devices with lower performance, consider increasing this value."`
TransparentHook string `id:"transparent-hook" desc:"the executable file to run in the transparent proxy life-cycle. v2rayA will pass in the --transparent-type (tproxy, redirect) and --stage (pre-start, post-start, pre-stop, post-stop) arguments."`
CoreHook string `id:"core-hook" desc:"the executable file to run in the v2ray-core life-cycle. v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument."`
PluginManager string `id:"plugin-manager" desc:"the executable file to run in the v2ray-core life-cycle. v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument."`
@@ -104,6 +105,10 @@ func initFunc() {
log.Fatal("failed to set V2rayAssetsDirectory: %v", err)
}
}
if params.CoreStartupTimeout <= 0 {
log.Fatal("invalid CoreStartupTimeout: %d seconds. It must be a positive integer greater than 0.", params.CoreStartupTimeout)
}
}
var once sync.Once

View File

@@ -36,6 +36,7 @@ type Subscription struct {
Status SubscriptionStatus `json:"status"`
Info string `json:"info"`
Servers []Server `json:"servers"`
AutoSelect bool `json:"autoSelect"`
}
func NewUpdateStatus() SubscriptionStatus {
@@ -93,6 +94,7 @@ func GenerateTouch() (t Touch) {
Status: SubscriptionStatus(v.Status),
Servers: serverRawsToServers(v.Servers),
Info: v.Info,
AutoSelect: v.AutoSelect,
}
}
t.ConnectedServers = configure.GetConnectedServers().Get()

View File

@@ -18,6 +18,7 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"
)
@@ -138,6 +139,7 @@ func NewProcess(tmpl *Template,
}
log.Trace("portList for connectivity test: %+v", portList)
startTime := time.Now()
startTimeOut := time.Duration(conf.GetEnvironmentConfig().CoreStartupTimeout) * time.Second
for i := 0; i < len(portList); {
conn, err := net.Dial("tcp", net.JoinHostPort("127.0.0.1", portList[i]))
if err == nil {
@@ -151,7 +153,9 @@ func NewProcess(tmpl *Template,
}
return nil, fmt.Errorf("unexpected exiting: check the log for more information")
}
if time.Since(startTime) > 30*time.Second {
if time.Since(startTime) > startTimeOut {
log.Info("Attempting to terminate timed-out process with SIGTERM")
_ = proc.Signal(syscall.SIGTERM)
return nil, fmt.Errorf("timeout: check the log for more information")
}
time.Sleep(100 * time.Millisecond)

View File

@@ -18,6 +18,7 @@ type SubscriptionRaw struct {
Status string `json:"status"` //update time, error info, etc.
Servers []ServerRaw `json:"servers"`
Info string `json:"info"` // maybe include some info from provider
AutoSelect bool `json:"autoSelect"`
}
func Bytes2SubscriptionRaw(b []byte) (*SubscriptionRaw, error) {
@@ -57,4 +58,4 @@ func Bytes2ServerRaw(b []byte) (*ServerRaw, error) {
return nil, err
}
return &s, nil
}
}

View File

@@ -225,6 +225,13 @@ func updateSubscriptions() {
subs := configure.GetSubscriptions()
lenSubs := len(subs)
control := make(chan struct{}, 2) //并发限制同时更新2个订阅
// Disconnect from subscriptions before auto-selecting servers from them
// to limit the number of connected servers and avoid hitting the limit
shouldDisconnect := true
err := service.AutoSelectServersFromSubscriptions(shouldDisconnect)
if err != nil {
log.Error("[AutoSelect] Failed to disconnect servers from subscriptions -- err: %v", err)
}
wg := new(sync.WaitGroup)
for i := 0; i < lenSubs; i++ {
wg.Add(1)
@@ -241,6 +248,12 @@ func updateSubscriptions() {
}(i)
}
wg.Wait()
shouldDisconnect = false
err2 := service.AutoSelectServersFromSubscriptions(shouldDisconnect)
if err2 != nil {
log.Error("[AutoSelect] Failed to auto-select servers from subscriptions -- err: %v", err2)
}
}
func initUpdatingTicker() {

View File

@@ -291,3 +291,28 @@ func httpLatency(which *configure.Which, port string, timeout time.Duration, cus
_ = resp.Body.Close()
which.Latency = fmt.Sprintf("%.0fms", time.Since(t).Seconds()*1000)
}
func IsSupported(which configure.Which) (bool, error) {
var (
tmpl *v2ray.Template
err error
)
tmpl = v2ray.NewEmptyTemplate(&configure.Setting{
RulePortMode: configure.WhitelistMode,
TcpFastOpen: configure.Default,
MuxOn: configure.No,
Transparent: configure.TransparentClose,
SpecialMode: configure.SpecialModeNone,
AntiPollution: configure.AntipollutionClosed,
})
tmpl.SetAPI(nil)
serverRaw, _ := which.LocateServerRaw()
err = tmpl.InsertMappingOutbound(serverRaw.ServerObj, "0", false, 0, "socks")
if err != nil {
if strings.Contains(err.Error(), "unsupported") {
return false, err
}
}
return true, nil
}

View File

@@ -4,14 +4,6 @@ import (
"bytes"
"errors"
"fmt"
jsoniter "github.com/json-iterator/go"
"github.com/v2rayA/v2rayA/common"
"github.com/v2rayA/v2rayA/common/httpClient"
"github.com/v2rayA/v2rayA/common/resolv"
"github.com/v2rayA/v2rayA/core/serverObj"
"github.com/v2rayA/v2rayA/core/touch"
"github.com/v2rayA/v2rayA/db/configure"
"github.com/v2rayA/v2rayA/pkg/util/log"
"io"
"net"
"net/http"
@@ -19,6 +11,16 @@ import (
"strconv"
"strings"
"time"
jsoniter "github.com/json-iterator/go"
"github.com/v2rayA/v2rayA/common"
"github.com/v2rayA/v2rayA/common/httpClient"
"github.com/v2rayA/v2rayA/common/resolv"
"github.com/v2rayA/v2rayA/core/serverObj"
"github.com/v2rayA/v2rayA/core/touch"
"github.com/v2rayA/v2rayA/core/v2ray/where"
"github.com/v2rayA/v2rayA/db/configure"
"github.com/v2rayA/v2rayA/pkg/util/log"
)
type SIP008 struct {
@@ -272,5 +274,86 @@ func ModifySubscriptionRemark(subscription touch.Subscription) (err error) {
}
raw.Remarks = subscription.Remarks
raw.Address = subscription.Address
raw.AutoSelect = subscription.AutoSelect
return configure.SetSubscription(subscription.ID-1, raw)
}
func SelectServersFromSubscription(index int, shouldDisconnect bool) (err error) {
var subscriptionServer configure.Which
subscriptionServer.TYPE = "subscriptionServer"
subscriptionServer.Sub = index // Subscription IDs start with 0
subscriptionServer.Outbound = "proxy"
variant, _, err := where.GetV2rayServiceVersion()
if err != nil {
log.Warn("Could not figure out if the server is running xray or v2ray -- err: %v", err)
}
for i := 1; i < configure.GetLenSubscriptionServers(index)+1; i++ {
subscriptionServer.ID = i // Server IDs start with 1
serverObj := configure.GetSubscription(index).Servers[i-1].ServerObj // ServerObj IDs start with 0
serverName := serverObj.GetName()
// Workaround for partial SS support in v2fly and xray
isSupported, _ := IsSupported(subscriptionServer)
if !isSupported {
log.Info("[AutoSelect] Skipping unsupported server %v", serverName)
continue
}
if shouldDisconnect && variant != where.Xray {
err := Disconnect(subscriptionServer, true)
if err == nil {
log.Info("[AutoSelect] Disconnected from server: %v", serverName)
} else {
log.Error("[AutoSelect] Failed to disconnect from server: %v", serverName)
return err
}
} else {
err := Connect(&subscriptionServer)
if err == nil {
log.Info("[AutoSelect] Automatically selected server: %v", serverName)
//Xray only supports connecting to one server at a time
if variant == where.Xray {
break
}
} else {
log.Error("[AutoSelect] Failed to connect to server: %v", serverName)
return err
}
}
}
return nil
}
func AutoSelectServersFromSubscriptions(shouldDisconnect bool) (err error) {
variant, _, err := where.GetV2rayServiceVersion()
if err != nil {
log.Warn("Could not figure out if the server is running xray or v2ray -- err: %v", err)
}
for i := 0; i < configure.GetLenSubscriptions(); i++ {
subscription := configure.GetSubscription(i)
if subscription.AutoSelect {
if shouldDisconnect && variant != where.Xray {
log.Info("[AutoSelect] Automatically disconnecting servers from subscription: %v", subscription.Address)
err := SelectServersFromSubscription(i, true)
if err != nil {
log.Error("[AutoSelect] Failed to disconnect servers from subscription: %v", subscription.Address)
return err
}
} else {
log.Info("[AutoSelect] Automatically selecting servers from subscription: %v", subscription.Address)
err := SelectServersFromSubscription(i, false)
//Xray only supports connecting to one server at a time,
//there's no point in selecting servers from multiple subscriptions
if variant == where.Xray {
break
}
if err != nil {
log.Error("[AutoSelect] Failed to select servers from subscription: %v", subscription.Address)
return err
}
}
}
}
return nil
}