mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-09 22:15:00 +03:00
feat: support Xray XDRIVE object storage relay transport (#10546)
This commit is contained in:
@@ -10,5 +10,6 @@ public enum ETransport
|
||||
h2,
|
||||
http,
|
||||
quic,
|
||||
grpc
|
||||
grpc,
|
||||
xdrive
|
||||
}
|
||||
|
||||
@@ -337,7 +337,8 @@ public class Global
|
||||
"kcp",
|
||||
"grpc",
|
||||
"ws",
|
||||
"httpupgrade"
|
||||
"httpupgrade",
|
||||
"xdrive"
|
||||
];
|
||||
|
||||
public static readonly List<string> KcpHeaderTypes =
|
||||
@@ -455,6 +456,18 @@ public class Global
|
||||
"stream-one"
|
||||
];
|
||||
|
||||
public static readonly List<string> XdriveServices = ["google-drive", "s3", "local"];
|
||||
|
||||
public static readonly List<string> XdriveProviders =
|
||||
[
|
||||
"Cloudflare R2",
|
||||
"Google Drive",
|
||||
"AWS S3 (Global)",
|
||||
"Yandex Cloud S3",
|
||||
"ArvanCloud S3",
|
||||
"Custom S3"
|
||||
];
|
||||
|
||||
public static readonly List<string> DomainStrategy =
|
||||
[
|
||||
"AsIs",
|
||||
|
||||
@@ -321,6 +321,7 @@ public class StreamSettings4Ray
|
||||
public HysteriaSettings4Ray? hysteriaSettings { get; set; }
|
||||
|
||||
public MasqueSettings4Ray? masqueSettings { get; set; }
|
||||
public XdriveSettings4Ray? xdriveSettings { get; set; }
|
||||
|
||||
public JsonObject? finalmask { get; set; }
|
||||
|
||||
@@ -462,6 +463,28 @@ public class MasqueWarpSettings4Ray
|
||||
public List<string>? address { get; set; }
|
||||
}
|
||||
|
||||
public class XdriveSettings4Ray
|
||||
{
|
||||
public string? service { get; set; }
|
||||
public string? remoteFolder { get; set; }
|
||||
public List<string>? secrets { get; set; }
|
||||
public S3Settings4Ray? s3 { get; set; }
|
||||
public int? segmentBytes { get; set; }
|
||||
public int? flushIntervalMs { get; set; }
|
||||
public int? pollIntervalMs { get; set; }
|
||||
public int? maxPollIntervalMs { get; set; }
|
||||
public int? eagerWindowMs { get; set; }
|
||||
public int? concurrency { get; set; }
|
||||
}
|
||||
|
||||
public class S3Settings4Ray
|
||||
{
|
||||
public string? endpoint { get; set; }
|
||||
public string? region { get; set; }
|
||||
public string? bucket { get; set; }
|
||||
public bool? pathStyle { get; set; }
|
||||
}
|
||||
|
||||
public class Finalmask4Ray
|
||||
{
|
||||
public List<Mask4Ray>? tcp { get; set; }
|
||||
|
||||
@@ -16,4 +16,13 @@ public record TransportExtraItem
|
||||
public string? KcpHeaderType { get; init; }
|
||||
public string? KcpSeed { get; init; }
|
||||
public int? KcpMtu { get; init; }
|
||||
|
||||
public string? XdriveService { get; init; }
|
||||
public string? XdriveRemoteFolder { get; init; }
|
||||
public string? XdriveSecrets { get; init; }
|
||||
public string? XdriveS3Endpoint { get; init; }
|
||||
public string? XdriveS3Region { get; init; }
|
||||
public string? XdriveS3Bucket { get; init; }
|
||||
public bool? XdriveS3PathStyle { get; init; }
|
||||
public string? XdriveExtra { get; init; }
|
||||
}
|
||||
|
||||
Generated
+118
-46
@@ -996,6 +996,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Columns 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuColumns {
|
||||
get {
|
||||
return ResourceManager.GetString("menuColumns", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Close Connection 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -1032,15 +1041,6 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Currently frozen first {0} column(s) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuCurrentlyFrozenColumns {
|
||||
get {
|
||||
return ResourceManager.GetString("menuCurrentlyFrozenColumns", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Latency Test 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -1185,15 +1185,6 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Freeze up to this column 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuFreezeToThisColumn {
|
||||
get {
|
||||
return ResourceManager.GetString("menuFreezeToThisColumn", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Full Config Template Setting 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -1239,15 +1230,6 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Hide this column 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuHideThisColumn {
|
||||
get {
|
||||
return ResourceManager.GetString("menuHideThisColumn", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Import Rules From Clipboard 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -1824,15 +1806,6 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Show columns 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuShowColumns {
|
||||
get {
|
||||
return ResourceManager.GetString("menuShowColumns", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Show or hide the main window 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2022,15 +1995,6 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Unfreeze all columns 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuUnfreezeAllColumns {
|
||||
get {
|
||||
return ResourceManager.GetString("menuUnfreezeAllColumns", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 {0} Website 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -4949,7 +4913,7 @@ namespace ServiceLib.Resx {
|
||||
return ResourceManager.GetString("TbSettingsTunAutoRoute", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 DNS mode 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -5516,5 +5480,113 @@ namespace ServiceLib.Resx {
|
||||
return ResourceManager.GetString("UpgradeAppNotExistTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Preset Provider 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveProvider {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveProvider", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 XDRIVE service 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveService {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveService", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Remote folder 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveRemoteFolder {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveRemoteFolder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Secrets (comma separated) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveSecrets {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveSecrets", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 S3 Endpoint 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveS3Endpoint {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveS3Endpoint", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 S3 Region 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveS3Region {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveS3Region", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 S3 Bucket 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveS3Bucket {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveS3Bucket", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 S3 Force Path Style 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveS3PathStyle {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveS3PathStyle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 XDRIVE Extra 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveExtra {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveExtra", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Raw JSON, format: { XdriveObject } 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string XdriveExtraTip {
|
||||
get {
|
||||
return ResourceManager.GetString("XdriveExtraTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 XDRIVE service 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TransportHeaderType6 {
|
||||
get {
|
||||
return ResourceManager.GetString("TransportHeaderType6", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 XDRIVE remote folder 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TransportPathTip6 {
|
||||
get {
|
||||
return ResourceManager.GetString("TransportPathTip6", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1902,4 +1902,40 @@ Təyin edildikdə sertifikat sabitlənəcək və "Təhlükəsiz olmayan əlaqəy
|
||||
<data name="TbSortingProcess" xml:space="preserve">
|
||||
<value>Proses</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>Təyin olunmuş təchizatçı</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>Saxlama xidməti (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>Uzaqdakı qovluq (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>Giriş açarları (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>S3 son nöqtəsi (Endpoint)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>S3 regionu (Region)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>S3 səbəti (Bucket)</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>S3 ünvanlama rejimi (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE əlavə parametrləri</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>Emal edilməmiş JSON, format: { Xdrive obyekti }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>XDRIVE xidməti</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>XDRIVE uzaqdakı qovluq</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1776,4 +1776,40 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuNewUpdate" xml:space="preserve">
|
||||
<value>New Update</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>ارائهدهنده پیشفرض</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>سرویس ذخیرهسازی (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>پوشه ریموت (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>کلیدهای دسترسی (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>آدرس اندپوینت S3</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>منطقه S3 (region)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>باکت S3 (bucket)</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>آدرسدهی مستقیم S3 (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>تنظیمات پیشرفته XDRIVE</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>فرمت JSON خام: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>سرویس XDRIVE</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>پوشه ریموت XDRIVE</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1770,4 +1770,40 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuNewUpdate" xml:space="preserve">
|
||||
<value>Nouvelle MAJ</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>Fournisseur prédéfini</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>Service de stockage (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>Dossier distant (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>Clés d'accès (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>Point de terminaison S3 (Endpoint)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>Région S3 (Region)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>Bucket S3</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>Mode d'adressage S3 (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE Extra</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>JSON brut, format : { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>Service XDRIVE</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>Dossier distant XDRIVE</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1773,4 +1773,40 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuNewUpdate" xml:space="preserve">
|
||||
<value>New Update</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>Előre beállított szolgáltató</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>Tárhelyszolgáltatás (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>Távoli mappa (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>Hozzáférési kulcsok (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>S3 végpont (Endpoint)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>S3 régió (Region)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>S3 tárhely (Bucket)</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>S3 elérési út stílus (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE Extra</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>Raw JSON, formátum: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>XDRIVE szolgáltatás</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>XDRIVE távoli mappa</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1797,4 +1797,40 @@ Tindakan "Ambil sertifikat" mungkin gagal jika sertifikat self-signed digunakan
|
||||
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
||||
<value>Memecah bagian akhir paket menjadi fragmen yang lebih kecil. Hal ini dapat memengaruhi throughput dan latensi.</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>Penyedia Preset</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>Layanan Penyimpanan (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>Folder Jarak Jauh (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>Kredensial Akses (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>Endpoint S3</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>Wilayah S3 (Region)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>Bucket S3</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>Gaya Jalur S3 (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE Ekstra</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>JSON mentah, format: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>Layanan XDRIVE</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>Folder jarak jauh XDRIVE</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1917,8 +1917,8 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="FillCorrectFakeIPv6Range" xml:space="preserve">
|
||||
<value>Enter a valid IPv6 CIDR range with at least two addresses, for example fc00::/18.</value>
|
||||
</data>
|
||||
<data name="menuShowColumns" xml:space="preserve">
|
||||
<value>Show columns</value>
|
||||
<data name="menuColumns" xml:space="preserve">
|
||||
<value>Columns</value>
|
||||
</data>
|
||||
<data name="TbWarp" xml:space="preserve">
|
||||
<value>Warp</value>
|
||||
@@ -1926,16 +1926,40 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="LvPreResolve" xml:space="preserve">
|
||||
<value>Pre-resolve server domains</value>
|
||||
</data>
|
||||
<data name="menuFreezeToThisColumn" xml:space="preserve">
|
||||
<value>Freeze up to this column</value>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>Preset Provider</value>
|
||||
</data>
|
||||
<data name="menuUnfreezeAllColumns" xml:space="preserve">
|
||||
<value>Unfreeze all columns</value>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>Storage service (service)</value>
|
||||
</data>
|
||||
<data name="menuCurrentlyFrozenColumns" xml:space="preserve">
|
||||
<value>Currently frozen first {0} column(s)</value>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>Remote folder (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="menuHideThisColumn" xml:space="preserve">
|
||||
<value>Hide this column</value>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>Secrets (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
</root>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>S3 Endpoint</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>S3 Region</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>S3 Bucket</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>S3 Force Path Style</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE Extra</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>Raw JSON, format: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>XDRIVE service</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>XDRIVE remote folder</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1908,4 +1908,40 @@
|
||||
<data name="menuAddMasqueServer" xml:space="preserve">
|
||||
<value>Добавить сервер [MASQUE]</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>Шаблон провайдера</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>Облачный сервис (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>Удаленная папка (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>Ключи доступа (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>Эндпоинт S3 (Endpoint)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>Регион S3 (Region)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>Бакет S3 (Bucket)</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>Режим адресации S3 (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>Дополнительные параметры XDRIVE (Extra)</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>Сырой JSON, формат: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>XDRIVE-сервис</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>Удаленная папка XDRIVE</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1909,8 +1909,8 @@
|
||||
<data name="FillCorrectFakeIPv6Range" xml:space="preserve">
|
||||
<value>请输入至少包含两个地址的有效 IPv6 网段,例如 fc00::/18。</value>
|
||||
</data>
|
||||
<data name="menuShowColumns" xml:space="preserve">
|
||||
<value>显示列</value>
|
||||
<data name="menuColumns" xml:space="preserve">
|
||||
<value>列</value>
|
||||
</data>
|
||||
<data name="TbWarp" xml:space="preserve">
|
||||
<value>Warp</value>
|
||||
@@ -1918,16 +1918,40 @@
|
||||
<data name="LvPreResolve" xml:space="preserve">
|
||||
<value>预解析节点域名</value>
|
||||
</data>
|
||||
<data name="menuFreezeToThisColumn" xml:space="preserve">
|
||||
<value>冻结至此列</value>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>预设服务商</value>
|
||||
</data>
|
||||
<data name="menuUnfreezeAllColumns" xml:space="preserve">
|
||||
<value>取消所有冻结</value>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>存储服务 (service)</value>
|
||||
</data>
|
||||
<data name="menuCurrentlyFrozenColumns" xml:space="preserve">
|
||||
<value>当前已冻结前 {0} 列</value>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>远程目录 (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="menuHideThisColumn" xml:space="preserve">
|
||||
<value>隐藏此列</value>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>访问凭证 Secrets (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
</root>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>S3 终端节点</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>S3 区域</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>S3 存储桶</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>S3 强制路径样式 (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE 额外配置</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>原始 JSON,格式: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>XDRIVE 服务</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>XDRIVE 远端目录</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1927,4 +1927,40 @@
|
||||
<data name="FillCorrectFakeIPv6Range" xml:space="preserve">
|
||||
<value>請輸入至少包含兩個位址的有效 IPv6 網段,例如 fc00::/18。</value>
|
||||
</data>
|
||||
<data name="XdriveProvider" xml:space="preserve">
|
||||
<value>預設服務商</value>
|
||||
</data>
|
||||
<data name="XdriveService" xml:space="preserve">
|
||||
<value>存儲服務 (service)</value>
|
||||
</data>
|
||||
<data name="XdriveRemoteFolder" xml:space="preserve">
|
||||
<value>遠端目錄 (remoteFolder)</value>
|
||||
</data>
|
||||
<data name="XdriveSecrets" xml:space="preserve">
|
||||
<value>存取憑證 Secrets (AK,SK / OAuth)</value>
|
||||
</data>
|
||||
<data name="XdriveS3Endpoint" xml:space="preserve">
|
||||
<value>S3 終端節點</value>
|
||||
</data>
|
||||
<data name="XdriveS3Region" xml:space="preserve">
|
||||
<value>S3 區域</value>
|
||||
</data>
|
||||
<data name="XdriveS3Bucket" xml:space="preserve">
|
||||
<value>S3 儲存桶</value>
|
||||
</data>
|
||||
<data name="XdriveS3PathStyle" xml:space="preserve">
|
||||
<value>S3 強制路徑樣式 (PathStyle)</value>
|
||||
</data>
|
||||
<data name="XdriveExtra" xml:space="preserve">
|
||||
<value>XDRIVE 額外配置</value>
|
||||
</data>
|
||||
<data name="XdriveExtraTip" xml:space="preserve">
|
||||
<value>原始 JSON,格式: { XdriveObject }</value>
|
||||
</data>
|
||||
<data name="TransportHeaderType6" xml:space="preserve">
|
||||
<value>XDRIVE 服務</value>
|
||||
</data>
|
||||
<data name="TransportPathTip6" xml:space="preserve">
|
||||
<value>XDRIVE 遠端目錄</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -506,6 +506,81 @@ public partial class CoreConfigV2rayService
|
||||
streamSettings.grpcSettings = grpcSettings;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xdrive):
|
||||
streamSettings.network = nameof(ETransport.xdrive);
|
||||
var xdriveSettings = new XdriveSettings4Ray
|
||||
{
|
||||
service = transport.XdriveService,
|
||||
remoteFolder = transport.XdriveRemoteFolder,
|
||||
secrets = transport.XdriveSecrets.IsNotEmpty() ? Utils.String2List(transport.XdriveSecrets) : null,
|
||||
};
|
||||
|
||||
if (string.Equals(transport.XdriveService, "s3", StringComparison.OrdinalIgnoreCase)
|
||||
|| transport.XdriveS3Endpoint.IsNotEmpty()
|
||||
|| transport.XdriveS3Bucket.IsNotEmpty())
|
||||
{
|
||||
xdriveSettings.s3 = new S3Settings4Ray
|
||||
{
|
||||
endpoint = transport.XdriveS3Endpoint,
|
||||
region = transport.XdriveS3Region,
|
||||
bucket = transport.XdriveS3Bucket,
|
||||
pathStyle = transport.XdriveS3PathStyle,
|
||||
};
|
||||
}
|
||||
|
||||
if (transport.XdriveExtra.IsNotEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
var extraNode = JsonUtils.ParseJson(transport.XdriveExtra);
|
||||
if (extraNode is JsonObject extraObj)
|
||||
{
|
||||
if (int.TryParse(extraObj["segmentBytes"]?.ToString(), out var segmentBytes))
|
||||
{
|
||||
xdriveSettings.segmentBytes = segmentBytes;
|
||||
}
|
||||
if (int.TryParse(extraObj["flushIntervalMs"]?.ToString(), out var flushIntervalMs))
|
||||
{
|
||||
xdriveSettings.flushIntervalMs = flushIntervalMs;
|
||||
}
|
||||
if (int.TryParse(extraObj["pollIntervalMs"]?.ToString(), out var pollIntervalMs))
|
||||
{
|
||||
xdriveSettings.pollIntervalMs = pollIntervalMs;
|
||||
}
|
||||
if (int.TryParse(extraObj["maxPollIntervalMs"]?.ToString(), out var maxPollIntervalMs))
|
||||
{
|
||||
xdriveSettings.maxPollIntervalMs = maxPollIntervalMs;
|
||||
}
|
||||
if (int.TryParse(extraObj["eagerWindowMs"]?.ToString(), out var eagerWindowMs))
|
||||
{
|
||||
xdriveSettings.eagerWindowMs = eagerWindowMs;
|
||||
}
|
||||
if (int.TryParse(extraObj["concurrency"]?.ToString(), out var concurrency))
|
||||
{
|
||||
xdriveSettings.concurrency = concurrency;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore extra json parse errors
|
||||
}
|
||||
}
|
||||
|
||||
if (string.Equals(transport.XdriveService, "google-drive", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xdriveSettings.segmentBytes ??= 524288;
|
||||
xdriveSettings.flushIntervalMs ??= 10;
|
||||
xdriveSettings.pollIntervalMs ??= 50;
|
||||
xdriveSettings.maxPollIntervalMs ??= 200;
|
||||
xdriveSettings.eagerWindowMs ??= 10000;
|
||||
xdriveSettings.concurrency ??= 64;
|
||||
}
|
||||
|
||||
streamSettings.xdriveSettings = xdriveSettings;
|
||||
FillOutboundMux(outbound, true, true);
|
||||
break;
|
||||
|
||||
case "hysteria":
|
||||
var ports = protocolExtra?.Ports;
|
||||
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
|
||||
|
||||
@@ -148,6 +148,33 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
[Reactive]
|
||||
public partial int? KcpMtu { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveProvider { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveService { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveRemoteFolder { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveSecrets { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveS3Endpoint { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveS3Region { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveS3Bucket { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial bool? XdriveS3PathStyle { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public partial string XdriveExtra { get; set; }
|
||||
|
||||
public string TransportHeaderType
|
||||
{
|
||||
get => SelectedSource.GetNetwork() switch
|
||||
@@ -156,6 +183,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
nameof(ETransport.kcp) => KcpHeaderType,
|
||||
nameof(ETransport.xhttp) => XhttpMode,
|
||||
nameof(ETransport.grpc) => GrpcMode,
|
||||
nameof(ETransport.xdrive) => XdriveService,
|
||||
_ => string.Empty,
|
||||
};
|
||||
set
|
||||
@@ -177,6 +205,10 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
case nameof(ETransport.grpc):
|
||||
GrpcMode = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xdrive):
|
||||
XdriveService = value;
|
||||
break;
|
||||
}
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
@@ -191,6 +223,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
nameof(ETransport.httpupgrade) => Host,
|
||||
nameof(ETransport.xhttp) => Host,
|
||||
nameof(ETransport.grpc) => GrpcAuthority,
|
||||
nameof(ETransport.xdrive) => XdriveS3Endpoint,
|
||||
_ => string.Empty,
|
||||
};
|
||||
set
|
||||
@@ -207,6 +240,10 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
case nameof(ETransport.grpc):
|
||||
GrpcAuthority = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xdrive):
|
||||
XdriveS3Endpoint = value;
|
||||
break;
|
||||
}
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
@@ -221,6 +258,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
nameof(ETransport.httpupgrade) => Path,
|
||||
nameof(ETransport.xhttp) => Path,
|
||||
nameof(ETransport.grpc) => GrpcServiceName,
|
||||
nameof(ETransport.xdrive) => XdriveRemoteFolder,
|
||||
_ => string.Empty,
|
||||
};
|
||||
set
|
||||
@@ -240,6 +278,10 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
case nameof(ETransport.grpc):
|
||||
GrpcServiceName = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xdrive):
|
||||
XdriveRemoteFolder = value;
|
||||
break;
|
||||
}
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
@@ -247,14 +289,23 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
|
||||
public string TransportExtraText
|
||||
{
|
||||
get => SelectedSource.GetNetwork() == nameof(ETransport.xhttp)
|
||||
? XhttpExtra
|
||||
: string.Empty;
|
||||
get => SelectedSource.GetNetwork() switch
|
||||
{
|
||||
nameof(ETransport.xhttp) => XhttpExtra,
|
||||
nameof(ETransport.xdrive) => XdriveExtra,
|
||||
_ => string.Empty,
|
||||
};
|
||||
set
|
||||
{
|
||||
if (SelectedSource.GetNetwork() == nameof(ETransport.xhttp))
|
||||
switch (SelectedSource.GetNetwork())
|
||||
{
|
||||
XhttpExtra = value;
|
||||
case nameof(ETransport.xhttp):
|
||||
XhttpExtra = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xdrive):
|
||||
XdriveExtra = value;
|
||||
break;
|
||||
}
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
@@ -287,8 +338,16 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
.Subscribe(_ => UpdateCertTip());
|
||||
|
||||
this.WhenAnyValue(x => x.Network)
|
||||
.Subscribe(_ =>
|
||||
.Subscribe(network =>
|
||||
{
|
||||
if (SelectedSource != null && !network.IsNullOrEmpty())
|
||||
{
|
||||
SelectedSource.Network = network;
|
||||
}
|
||||
if (network == nameof(ETransport.xdrive))
|
||||
{
|
||||
MuxEnabled = true;
|
||||
}
|
||||
this.RaisePropertyChanged(nameof(TransportHeaderType));
|
||||
this.RaisePropertyChanged(nameof(TransportHost));
|
||||
this.RaisePropertyChanged(nameof(TransportPath));
|
||||
@@ -298,6 +357,13 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
this.WhenAnyValue(x => x.Cert)
|
||||
.Subscribe(_ => UpdateCertSha());
|
||||
|
||||
this.WhenAnyValue(x => x.XdriveProvider)
|
||||
.Where(p => p.IsNotEmpty())
|
||||
.Subscribe(provider =>
|
||||
{
|
||||
ApplyXdriveProviderPreset(provider);
|
||||
});
|
||||
|
||||
if (profileItem.IndexId.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.Network = Global.DefaultNetwork;
|
||||
@@ -358,6 +424,48 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
KcpHeaderType = transport.KcpHeaderType.IsNullOrEmpty() ? Global.None : transport.KcpHeaderType;
|
||||
KcpSeed = transport.KcpSeed ?? string.Empty;
|
||||
KcpMtu = transport.KcpMtu;
|
||||
XdriveService = transport.XdriveService.IsNullOrEmpty() ? (Global.XdriveServices.FirstOrDefault() ?? "google-drive") : transport.XdriveService;
|
||||
XdriveRemoteFolder = transport.XdriveRemoteFolder ?? string.Empty;
|
||||
XdriveSecrets = transport.XdriveSecrets ?? string.Empty;
|
||||
XdriveS3Endpoint = transport.XdriveS3Endpoint ?? string.Empty;
|
||||
XdriveS3Region = transport.XdriveS3Region ?? string.Empty;
|
||||
XdriveS3Bucket = transport.XdriveS3Bucket ?? string.Empty;
|
||||
XdriveS3PathStyle = transport.XdriveS3PathStyle;
|
||||
XdriveExtra = transport.XdriveExtra ?? string.Empty;
|
||||
|
||||
if (transport.XdriveService == "google-drive")
|
||||
{
|
||||
XdriveProvider = "Google Drive";
|
||||
}
|
||||
else if (transport.XdriveS3Endpoint?.Contains("r2.cloudflarestorage.com") == true)
|
||||
{
|
||||
XdriveProvider = "Cloudflare R2";
|
||||
}
|
||||
else if (transport.XdriveS3Endpoint?.Contains("amazonaws.com") == true)
|
||||
{
|
||||
XdriveProvider = "AWS S3 (Global)";
|
||||
}
|
||||
else if (transport.XdriveS3Endpoint?.Contains("yandexcloud.net") == true)
|
||||
{
|
||||
XdriveProvider = "Yandex Cloud S3";
|
||||
}
|
||||
else if (transport.XdriveS3Endpoint?.Contains("arvanstorage.ir") == true)
|
||||
{
|
||||
XdriveProvider = "ArvanCloud S3";
|
||||
}
|
||||
else if (SelectedSource.Remarks?.Contains("Cloudflare", StringComparison.OrdinalIgnoreCase) == true
|
||||
|| (transport.XdriveS3PathStyle == true && transport.XdriveS3Region == "auto"))
|
||||
{
|
||||
XdriveProvider = "Cloudflare R2";
|
||||
}
|
||||
else if (transport.XdriveService == "s3" || transport.XdriveS3Endpoint.IsNotEmpty())
|
||||
{
|
||||
XdriveProvider = "Custom S3";
|
||||
}
|
||||
else
|
||||
{
|
||||
XdriveProvider = "Cloudflare R2";
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveServerAsync()
|
||||
@@ -440,6 +548,14 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
KcpHeaderType = KcpHeaderType.NullIfEmpty(),
|
||||
KcpSeed = KcpSeed.NullIfEmpty(),
|
||||
KcpMtu = KcpMtu > 0 ? KcpMtu : null,
|
||||
XdriveService = XdriveService.NullIfEmpty(),
|
||||
XdriveRemoteFolder = XdriveRemoteFolder.NullIfEmpty(),
|
||||
XdriveSecrets = XdriveSecrets.NullIfEmpty(),
|
||||
XdriveS3Endpoint = XdriveS3Endpoint.NullIfEmpty(),
|
||||
XdriveS3Region = XdriveS3Region.NullIfEmpty(),
|
||||
XdriveS3Bucket = XdriveS3Bucket.NullIfEmpty(),
|
||||
XdriveS3PathStyle = XdriveS3PathStyle,
|
||||
XdriveExtra = XdriveExtra.NullIfEmpty(),
|
||||
};
|
||||
|
||||
SelectedSource.SetProtocolExtra(SelectedSource.GetProtocolExtra() with
|
||||
@@ -494,6 +610,44 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
: errorMessage;
|
||||
}
|
||||
|
||||
private void ApplyXdriveProviderPreset(string provider)
|
||||
{
|
||||
switch (provider)
|
||||
{
|
||||
case "Cloudflare R2":
|
||||
XdriveService = "s3";
|
||||
if (XdriveS3Region.IsNullOrEmpty()) XdriveS3Region = "auto";
|
||||
XdriveS3PathStyle = true;
|
||||
break;
|
||||
case "Google Drive":
|
||||
XdriveService = "google-drive";
|
||||
SelectedSource.StreamSecurity = Global.StreamSecurity;
|
||||
if (SelectedSource.Sni.IsNullOrEmpty()) SelectedSource.Sni = "www.google.com";
|
||||
if (SelectedSource.Alpn.IsNullOrEmpty()) SelectedSource.Alpn = "h2";
|
||||
if (SelectedSource.Address.IsNullOrEmpty()) SelectedSource.Address = "www.google.com";
|
||||
if (SelectedSource.Port <= 0) SelectedSource.Port = 443;
|
||||
break;
|
||||
case "AWS S3 (Global)":
|
||||
XdriveService = "s3";
|
||||
if (XdriveS3Region.IsNullOrEmpty()) XdriveS3Region = "ap-northeast-1";
|
||||
XdriveS3PathStyle = false;
|
||||
break;
|
||||
case "Yandex Cloud S3":
|
||||
XdriveService = "s3";
|
||||
if (XdriveS3Region.IsNullOrEmpty()) XdriveS3Region = "ru-central1";
|
||||
XdriveS3PathStyle = true;
|
||||
break;
|
||||
case "ArvanCloud S3":
|
||||
XdriveService = "s3";
|
||||
if (XdriveS3Region.IsNullOrEmpty()) XdriveS3Region = "ir-tbz-sh1";
|
||||
XdriveS3PathStyle = true;
|
||||
break;
|
||||
case "Custom S3":
|
||||
XdriveService = "s3";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCertSha()
|
||||
{
|
||||
if (Cert.IsNullOrEmpty())
|
||||
@@ -582,6 +736,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
|
||||
nameof(ETransport.httpupgrade) => Host,
|
||||
nameof(ETransport.xhttp) => Host,
|
||||
nameof(ETransport.grpc) => GrpcAuthority,
|
||||
nameof(ETransport.xdrive) => XdriveS3Endpoint,
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user