mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Mon Oct 14 20:35:22 CEST 2024
This commit is contained in:
@@ -793,3 +793,4 @@ Update On Thu Oct 10 20:36:48 CEST 2024
|
||||
Update On Fri Oct 11 20:34:02 CEST 2024
|
||||
Update On Sat Oct 12 20:32:54 CEST 2024
|
||||
Update On Sun Oct 13 20:32:23 CEST 2024
|
||||
Update On Mon Oct 14 20:35:11 CEST 2024
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="geofile_import_failed">Nhập thất bại</string>
|
||||
<string name="toast_profile_updated_complete">Cập nhật thành công</string>
|
||||
<string name="toast_profile_updated_failed">Cập nhật không thành công</string>
|
||||
<string name="press_to_import">Chạm để nhập...</string>
|
||||
<string name="meta_features">Tính năng của Clash Meta</string>
|
||||
<string name="allow_ipv6">Cho phép Ipv6</string>
|
||||
<string name="allow_ipv6_summary">Cho phép lưu lượng ipv6 qua hệ thống Vpn</string>
|
||||
<string name="tun_stack_gvisor">Gvisor</string>
|
||||
<string name="tun_stack_mixed">Mixed</string>
|
||||
<string name="tun_stack_mode">Chế độ xếp chồng dữ liệu</string>
|
||||
<string name="tun_stack_system">Hệ thống</string>
|
||||
<string name="application_name_alpha">Clash Meta</string>
|
||||
<string name="application_name_meta">Clash Meta</string>
|
||||
<string name="clash_meta_core">Clash Meta Core</string>
|
||||
<string name="clash_meta_for_android">Clash Meta</string>
|
||||
<string name="clash_meta_wiki">Clash Meta Wiki</string>
|
||||
<string name="launch_name_alpha">Clash Meta</string>
|
||||
<string name="launch_name_meta">Clash Meta</string>
|
||||
<string name="_new">Mới</string>
|
||||
<string name="about">Thông tin</string>
|
||||
<string name="accept_http_content">Chỉ chấp nhận http(s)</string>
|
||||
<string name="access_control_mode">Chế độ kiểm soát truy cập</string>
|
||||
<string name="access_control_packages">Các gói kiểm soát truy cập</string>
|
||||
<string name="access_control_packages_summary">Định cấu hình quyền truy cập cho các ứng dụng</string>
|
||||
<string name="active_unsaved_tips">Hồ sơ cần được lưu trước khi kích hoạt</string>
|
||||
<string name="allow_all_apps">Cho phép tất cả các ứng dụng</string>
|
||||
<string name="allow_bypass">Cho phép bỏ qua</string>
|
||||
<string name="allow_bypass_summary">Cho phép tất cả các ứng dụng bỏ qua kết nối VPN này</string>
|
||||
<string name="allow_clash_auto_restart">Cho phép Clash tự khởi động lại</string>
|
||||
<string name="allow_lan">Cho phép mạng LAN</string>
|
||||
<string name="allow_selected_apps">Cho phép các ứng dụng đã chọn</string>
|
||||
<string name="always_dark">Luôn tối</string>
|
||||
<string name="always_light">Luôn sáng</string>
|
||||
<string name="app">Ứng dụng</string>
|
||||
<string name="append_system_dns">Nối hệ thống DNS</string>
|
||||
<string name="application_broken">Ứng dụng bị lỗi</string>
|
||||
<string name="application_broken_tips">Ứng dụng thiếu các thành phần cần thiết, nguyên nhân thường là do tải xuống apk không đầy đủ.</string>
|
||||
<string name="application_crashed">Ứng dụng bị dừng</string>
|
||||
<string name="at_least_15_minutes">Ít nhất 15 phút hoặc để trống</string>
|
||||
<string name="authentication">Xác thực</string>
|
||||
<string name="auto_restart">Khởi động lại tự động</string>
|
||||
<string name="auto_update">Thời gian tự động cập nhật</string>
|
||||
<string name="auto_update_minutes">Tự động cập nhật (Phút)</string>
|
||||
<string name="behavior">Điều hướng</string>
|
||||
<string name="bind_address">Địa chỉ ràng buộc</string>
|
||||
<string name="block_loopback">Chặn lặp</string>
|
||||
<string name="block_loopback_summary">Chặn kết nối lặp lại</string>
|
||||
<string name="browse_configuration_providers">Duyệt qua tệp cấu hình và nhà cung cấp</string>
|
||||
<string name="browse_files">Duyệt qua tệp</string>
|
||||
<string name="bypass_private_network">Bỏ qua mạng riêng</string>
|
||||
<string name="bypass_private_network_summary">Bỏ qua các địa chỉ mạng riêng</string>
|
||||
<string name="cancel">Huỷ bỏ</string>
|
||||
<string name="clash_logcat">Nhật ký Clash</string>
|
||||
<string name="close">Đóng</string>
|
||||
<string name="compatible">Tương thích</string>
|
||||
<string name="copied">Đã sao chép</string>
|
||||
<string name="create_profile">Tạo cấu hình</string>
|
||||
<string name="dark_mode">Chế độ tối</string>
|
||||
<string name="debug">Gỡ lỗi</string>
|
||||
<string name="default_">Mặc định</string>
|
||||
<string name="default_name_server">Máy chủ định danh mặc định</string>
|
||||
<string name="delay">Độ trễ</string>
|
||||
<string name="delay_test">Kiểm tra độ trễ</string>
|
||||
<string name="delete">Xoá</string>
|
||||
<string name="delete_all_logs">Xóa tất cả nhật ký</string>
|
||||
<string name="delete_all_logs_warn">Tất cả nhật ký lịch sử sẽ *MẤT*</string>
|
||||
<string name="deny_selected_apps">Từ chối các ứng dụng đã chọn</string>
|
||||
<string name="detail">Chi tiết</string>
|
||||
<string name="direct_mode">Chế độ trực tiếp</string>
|
||||
<string name="disabled">Vô hiệu hóa</string>
|
||||
<string name="dns">DNS</string>
|
||||
<string name="dns_hijacking">Định tuyến qua DNS</string>
|
||||
<string name="dns_hijacking_summary">Xử lý tất cả gói DNS</string>
|
||||
<string name="document">Tài liệu</string>
|
||||
<string name="domain_fallback">Dự phòng miền</string>
|
||||
<string name="donate">Quyên góp</string>
|
||||
<string name="dont_modify">Chưa sửa đổi</string>
|
||||
<string name="duplicate">Tạo bản sao</string>
|
||||
<string name="edit">Sửa</string>
|
||||
<string name="empty">Trống</string>
|
||||
<string name="empty_name">Tên trống</string>
|
||||
<string name="enabled">Bật</string>
|
||||
<string name="enhanced_mode">Chế độ nâng cao</string>
|
||||
<string name="error">Lỗi</string>
|
||||
<string name="exit_without_save">Thoát mà không lưu</string>
|
||||
<string name="exit_without_save_warning">Tất cả thay đổi sẽ *MẤT*</string>
|
||||
<string name="export">Xuất</string>
|
||||
<string name="export_to_clipboard">Nhập từ khay nhớ tạm</string>
|
||||
<string name="external">Bên ngoài</string>
|
||||
<string name="fakeip">Fake-IP thành ánh xạ miền</string>
|
||||
<string name="fakeip_filter">Bộ lọc Fake-IP</string>
|
||||
<string name="fallback">Máy chủ tên dự phòng</string>
|
||||
<string name="feedback">Phản hồi</string>
|
||||
<string name="file">Tệp</string>
|
||||
<string name="file_exported">Tệp đã xuất</string>
|
||||
<string name="file_name">Tên tệp</string>
|
||||
<string name="files">Tệp</string>
|
||||
<string name="filter">Bộ lọc</string>
|
||||
<string name="follow_system_android_10">Theo hệ thống (Android 10+)</string>
|
||||
<string name="force_enable">Buộc bật</string>
|
||||
<string name="format_days_ago">%d ngày trước</string>
|
||||
<string name="format_elements">%d elements</string>
|
||||
<string name="format_fetching_configuration">Tìm nạp cấu hình từ \'%s\'</string>
|
||||
<string name="format_fetching_provider">Nhà cung cấp tìm nạp \'%s\'</string>
|
||||
<string name="format_hours_ago">%d giờ trước</string>
|
||||
<string name="format_minutes">%d phút</string>
|
||||
<string name="format_minutes_ago">%d phút trước</string>
|
||||
<string name="format_months_ago">%d tháng trước</string>
|
||||
<string name="format_profile_activated">%s đang sử dụng</string>
|
||||
<string name="format_provider_type">%1$s(%2$s)</string>
|
||||
<string name="format_traffic_forwarded">%s được sử dụng</string>
|
||||
<string name="format_type_unsaved">%s (Chưa lưu)</string>
|
||||
<string name="format_update_complete">Cập nhật %s thành công</string>
|
||||
<string name="format_update_failure">Cập nhật %1$s: %2$s</string>
|
||||
<string name="format_update_provider_failure">Cập nhật %1$s: %2$s</string>
|
||||
<string name="format_years_ago">%d năm trước</string>
|
||||
<string name="general">Chung</string>
|
||||
<string name="geoip_fallback">Dự phòng GeoIP</string>
|
||||
<string name="geoip_fallback_code">Mã dự phòng GeoIP</string>
|
||||
<string name="github_issues">Sự cố trên Github</string>
|
||||
<string name="github_releases">Bản phát hành trên Github</string>
|
||||
<string name="global_mode">Chế độ toàn cầu</string>
|
||||
<string name="help">Trợ giúp</string>
|
||||
<string name="history">Lịch sử</string>
|
||||
<string name="hosts">Hosts</string>
|
||||
<string name="http">HTTP</string>
|
||||
<string name="http_port">Cổng HTTP</string>
|
||||
<string name="import_">Nhập</string>
|
||||
<string name="import_from_clipboard">Nhập từ khay nhớ tạm</string>
|
||||
<string name="import_from_file">Nhập từ tệp</string>
|
||||
<string name="import_from_url">Nhập từ liên kết URL</string>
|
||||
<string name="info">Thông tin</string>
|
||||
<string name="initializing">Khởi tạo</string>
|
||||
<string name="install_time">Thời gian cài đặt</string>
|
||||
<string name="interface_">Giao diện</string>
|
||||
<string name="invalid_file_name">Tên tệp không hợp lệ</string>
|
||||
<string name="invalid_log_file">Tệp nhật ký không hợp lệ</string>
|
||||
<string name="invalid_url">Liên kết URL không hợp lệ</string>
|
||||
<string name="ipcidr_fallback">Dự phòng IPCIDR</string>
|
||||
<string name="ipv6">IPv6</string>
|
||||
<string name="key">Khoá</string>
|
||||
<string name="keyword">Từ khoá</string>
|
||||
<string name="layout">Bố cục</string>
|
||||
<string name="listen">Nghe</string>
|
||||
<string name="loading">Đang tải</string>
|
||||
<string name="log_level">Mức nhật ký</string>
|
||||
<string name="logcat">Nhật ký</string>
|
||||
<string name="logs">Nhật ký</string>
|
||||
<string name="mapping">IP thực với ánh xạ miền</string>
|
||||
<string name="mixed_port">Cổng Mixed</string>
|
||||
<string name="mode">Chế độ</string>
|
||||
<string name="mode_switch_tips">Chỉ hợp lệ cho phiên hiện tại</string>
|
||||
<string name="more">Thêm</string>
|
||||
<string name="multiple">Nhiều</string>
|
||||
<string name="name">Tên</string>
|
||||
<string name="name_server">Tên máy chủ</string>
|
||||
<string name="name_server_policy">Chính sách máy chủ định danh</string>
|
||||
<string name="network">Mạng</string>
|
||||
<string name="new_profile">Cấu hình mới</string>
|
||||
<string name="no_profile_selected">Không có cấu hình</string>
|
||||
<string name="not_selectable">Không thể chọn</string>
|
||||
<string name="not_selected">Trống. Nhấn vào để thêm</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="options_unavailable">Tùy chọn không khả dụng cho đến khi Clash ngắt kết nối</string>
|
||||
<string name="override">Cài đặt thêm</string>
|
||||
<string name="package_name">Tên gói</string>
|
||||
<string name="profile">Cấu hình</string>
|
||||
<string name="profile_name">Tên cấu hình</string>
|
||||
<string name="profile_process_result">Kết quả xử lý cấu hình</string>
|
||||
<string name="profile_process_status">Trạng thái xử lý cấu hình</string>
|
||||
<string name="profile_service_status">Trạng thái dịch vụ cấu hình</string>
|
||||
<string name="profile_updater">Trình cập nhật cấu hình</string>
|
||||
<string name="profile_updating">Cập nhật cấu hình</string>
|
||||
<string name="profile_url">Liên kết URL cấu hình</string>
|
||||
<string name="profiles">Cấu hình</string>
|
||||
<string name="properties">Thuộc tính</string>
|
||||
<string name="provider_files">Tệp nhà cung cấp</string>
|
||||
<string name="providers">Nhà cung cấp</string>
|
||||
<string name="proxy">Proxy</string>
|
||||
<string name="proxy_empty_tips">Không có nhóm nào được hiển thị</string>
|
||||
<string name="recently">Vừa xong</string>
|
||||
<string name="redirect_port">Cổng Redirect</string>
|
||||
<string name="reinstall">Cài đặt lại</string>
|
||||
<string name="rename">Đổi tên</string>
|
||||
<string name="reset">Đặt lại</string>
|
||||
<string name="reset_override_settings">Đặt lại cài đặt ghi đè</string>
|
||||
<string name="reset_override_settings_message">Tất cả cài đặt ghi đè sẽ bị hủy</string>
|
||||
<string name="reverse">Đảo ngược</string>
|
||||
<string name="route_system_traffic">Định tuyến lưu lượng hệ thống</string>
|
||||
<string name="routing_via_vpn_service">Tự động định tuyến tất cả lưu lượng hệ thống qua VpnService</string>
|
||||
<string name="rule">Quy tắc</string>
|
||||
<string name="rule_mode">Chế độ quy tắc</string>
|
||||
<string name="running">Đang kết nối</string>
|
||||
<string name="save">Lưu</string>
|
||||
<string name="script_mode">Chế độ tập lệnh</string>
|
||||
<string name="search">Tìm kiếm</string>
|
||||
<string name="select_all">Chọn tất cả</string>
|
||||
<string name="select_invert">Chọn Đảo ngược</string>
|
||||
<string name="select_none">Không chọn</string>
|
||||
<string name="service">Dịch vụ</string>
|
||||
<string name="settings">Cài đặt</string>
|
||||
<string name="should_not_be_blank">Không được để trống</string>
|
||||
<string name="show_traffic">Hiển thị lưu lượng truy cập</string>
|
||||
<string name="show_traffic_summary">Tự động làm mới lưu lượng truy cập trong thông báo</string>
|
||||
<string name="sideload_geoip">Sideload GEOIP</string>
|
||||
<string name="sideload_geoip_summary">Cơ sở dữ liệu GEOIP bên ngoài</string>
|
||||
<string name="silent">Im lặng</string>
|
||||
<string name="single">Đơn</string>
|
||||
<string name="socks_port">Cổng Socks</string>
|
||||
<string name="sort">Sắp xếp theo</string>
|
||||
<string name="sources">Nguồn</string>
|
||||
<string name="stopped">Đã ngắt kết nối</string>
|
||||
<string name="strategy">Strategy</string>
|
||||
<string name="system_apps">Ứng dụng hệ thống</string>
|
||||
<string name="system_proxy">Proxy hệ thống</string>
|
||||
<string name="system_proxy_summary">Đính kèm proxy,http vào hệ thống Vpn</string>
|
||||
<string name="tap_to_start">Chạm để kết nối</string>
|
||||
<string name="tips_help">Clash Meta là một phần mềm miễn phí và chúng tôi KHÔNG cung cấp bất kỳ dịch vụ trả phí nào cho nó</string>
|
||||
<string name="tips_properties">Chỉ chấp nhận cấu hình Clash bao gồm Proxy và Quy tắc</string>
|
||||
<string name="tproxy_port">Cổng TProxy</string>
|
||||
<string name="unable_to_start_vpn">Không thể khởi động thành phần VPN</string>
|
||||
<string name="unavailable">Không có sẵn</string>
|
||||
<string name="update">Cập nhật</string>
|
||||
<string name="update_all">Cập nhật tất cả</string>
|
||||
<string name="update_failure">Cập nhật thất bại</string>
|
||||
<string name="update_successfully">Cập nhật thành công</string>
|
||||
<string name="update_time">Thời gian cập nhật</string>
|
||||
<string name="url">Liên kết URL</string>
|
||||
<string name="use_built_in">Sử dụng tích hợp</string>
|
||||
<string name="use_hosts">Sử dụng Hosts</string>
|
||||
<string name="value">Giá trị</string>
|
||||
<string name="verifying">Đang xác minh</string>
|
||||
<string name="version_updated">Đã cập nhật ứng dụng</string>
|
||||
<string name="version_updated_tips">Các cài đặt đã được đặt lại và các cấu hình cũ cần được lưu lại.</string>
|
||||
<string name="vpn_service_options">Tuỳ chọn VpnService</string>
|
||||
<string name="warning">Cảnh báo</string>
|
||||
</resources>
|
||||
@@ -29,7 +29,7 @@
|
||||
"country-code-emoji": "2.3.0",
|
||||
"dayjs": "1.11.13",
|
||||
"framer-motion": "12.0.0-alpha.1",
|
||||
"i18next": "23.15.2",
|
||||
"i18next": "23.16.0",
|
||||
"jotai": "2.10.0",
|
||||
"json-schema": "0.4.0",
|
||||
"material-react-table": "3.0.1",
|
||||
@@ -52,7 +52,7 @@
|
||||
"@csstools/normalize.css": "12.1.1",
|
||||
"@emotion/babel-plugin": "11.12.0",
|
||||
"@emotion/react": "11.13.3",
|
||||
"@iconify/json": "2.2.259",
|
||||
"@iconify/json": "2.2.260",
|
||||
"@monaco-editor/react": "4.6.0",
|
||||
"@tanstack/react-router": "1.65.0",
|
||||
"@tanstack/router-devtools": "1.65.0",
|
||||
|
||||
Generated
+293
-293
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,16 @@ struct dentry;
|
||||
struct inode;
|
||||
struct file;
|
||||
|
||||
typedef enum rtl8367b_chip_e {
|
||||
RTL8367B_CHIP_UNKNOWN,
|
||||
/* Family B */
|
||||
RTL8367B_CHIP_RTL8367RB,
|
||||
RTL8367B_CHIP_RTL8367R_VB, /* chip with exception in extif assignment */
|
||||
/* Family C */
|
||||
RTL8367B_CHIP_RTL8367RB_VB,
|
||||
RTL8367B_CHIP_RTL8367S
|
||||
} rtl8367b_chip_t;
|
||||
|
||||
struct rtl8366_mib_counter {
|
||||
unsigned base;
|
||||
unsigned offset;
|
||||
@@ -64,6 +74,7 @@ struct rtl8366_smi {
|
||||
u8 dbg_vlan_4k_page;
|
||||
#endif
|
||||
u32 phy_id;
|
||||
rtl8367b_chip_t rtl8367b_chip;
|
||||
struct mii_bus *ext_mbus;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Platform driver for the Realtek RTL8367R-VB ethernet switches
|
||||
* Platform driver for Realtek RTL8367B family chips, i.e. RTL8367RB and RTL8367R-VB
|
||||
* extended with support for RTL8367C family chips, i.e. RTL8367RB-VB and RTL8367S
|
||||
*
|
||||
* Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
@@ -515,28 +516,19 @@ static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi,
|
||||
static int rtl8367b_init_regs(struct rtl8366_smi *smi)
|
||||
{
|
||||
const struct rtl8367b_initval *initvals;
|
||||
u32 chip_num;
|
||||
u32 chip_ver;
|
||||
int count;
|
||||
int err;
|
||||
|
||||
REG_WR(smi, RTL8367B_RTL_MAGIC_ID_REG, RTL8367B_RTL_MAGIC_ID_VAL);
|
||||
REG_RD(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num);
|
||||
REG_RD(smi, RTL8367B_CHIP_VER_REG, &chip_ver);
|
||||
|
||||
switch (chip_ver) {
|
||||
case 0x1000:
|
||||
case 0x1010:
|
||||
switch (smi->rtl8367b_chip) {
|
||||
case RTL8367B_CHIP_RTL8367RB:
|
||||
case RTL8367B_CHIP_RTL8367R_VB:
|
||||
initvals = rtl8367b_initvals;
|
||||
count = ARRAY_SIZE(rtl8367b_initvals);
|
||||
break;
|
||||
case 0x0020:
|
||||
case 0x00A0:
|
||||
if (chip_num == 0x6367) {
|
||||
initvals = rtl8367c_initvals;
|
||||
count = ARRAY_SIZE(rtl8367c_initvals);
|
||||
} else return -ENODEV;
|
||||
break
|
||||
case RTL8367B_CHIP_RTL8367RB_VB:
|
||||
case RTL8367B_CHIP_RTL8367S:
|
||||
initvals = rtl8367c_initvals;
|
||||
count = ARRAY_SIZE(rtl8367c_initvals);
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
@@ -1308,10 +1300,10 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
|
||||
const char *chip_name = NULL;
|
||||
u32 chip_num;
|
||||
u32 chip_ver;
|
||||
u32 chip_mode;
|
||||
int ret;
|
||||
|
||||
/* TODO: improve chip detection */
|
||||
smi->rtl8367b_chip = RTL8367B_CHIP_UNKNOWN;
|
||||
|
||||
rtl8366_smi_write_reg(smi, RTL8367B_RTL_MAGIC_ID_REG,
|
||||
RTL8367B_RTL_MAGIC_ID_VAL);
|
||||
|
||||
@@ -1329,41 +1321,41 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rtl8366_smi_read_reg(smi, RTL8367B_CHIP_MODE_REG, &chip_mode);
|
||||
if (ret) {
|
||||
dev_err(smi->parent, "unable to read %s register\n",
|
||||
"chip mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (chip_ver) {
|
||||
case 0x0020:
|
||||
if (chip_num == 0x6367)
|
||||
if (chip_num == 0x6367) {
|
||||
chip_name = "8367RB-VB";
|
||||
smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB_VB;
|
||||
}
|
||||
break;
|
||||
case 0x00A0:
|
||||
if (chip_num == 0x6367)
|
||||
if (chip_num == 0x6367) {
|
||||
chip_name = "8367S";
|
||||
smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S;
|
||||
}
|
||||
break;
|
||||
case 0x1000:
|
||||
chip_name = "8367RB";
|
||||
smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB;
|
||||
break;
|
||||
case 0x1010:
|
||||
chip_name = "8367R-VB";
|
||||
smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367R_VB;
|
||||
}
|
||||
|
||||
if (!chip_name) {
|
||||
dev_err(smi->parent,
|
||||
"unknown chip num:%04x ver:%04x, mode:%04x\n",
|
||||
chip_num, chip_ver, chip_mode);
|
||||
"unknown chip (num:%04x ver:%04x)\n",
|
||||
chip_num, chip_ver);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(smi->parent, "RTL%s chip found\n", chip_name);
|
||||
dev_info(smi->parent, "RTL%s chip found (num:%04x ver:%04x)\n", chip_name, chip_num, chip_ver);
|
||||
|
||||
/* for the RTL8367R-VB chip, extif1 corresponds to cpu_port 5 */
|
||||
if (of_property_present(smi->parent->of_node, "realtek,extif2"))
|
||||
smi->cpu_port = RTL8367B_CPU_PORT_NUM + 2;
|
||||
else if (of_property_present(smi->parent->of_node, "realtek,extif1") && (chip_ver != 0x1010)) /* for the RTL8367R-VB chip, extif1 corresponds to cpu_port 5 */
|
||||
else if (of_property_present(smi->parent->of_node, "realtek,extif1") && (smi->rtl8367b_chip != RTL8367B_CHIP_RTL8367R_VB))
|
||||
smi->cpu_port = RTL8367B_CPU_PORT_NUM + 1;
|
||||
|
||||
dev_info(smi->parent, "CPU port: %u\n", smi->cpu_port);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
# Copyright (C) 2021 ImmortalWrt
|
||||
# <https://immortalwrt.org>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
@@ -9,6 +11,11 @@ LUCI_TITLE:=LuCI Support for FileBrowser
|
||||
LUCI_DEPENDS:=+filebrowser
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_NAME:=luci-app-filebrowser
|
||||
PKG_VERSION:=snapshot
|
||||
PKG_RELEASE:=118071b
|
||||
|
||||
PKG_LICENSE:=GPLv3
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
@@ -1,59 +1,19 @@
|
||||
-- Copyright 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
-- Improve by xiaozhuai <xiaozhuai7@gmail.com>
|
||||
module("luci.controller.filebrowser", package.seeall)
|
||||
|
||||
local http = require "luci.http"
|
||||
local api = require "luci.model.cbi.filebrowser.api"
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/filebrowser") then return end
|
||||
|
||||
entry({"admin", "services"}, firstchild(), "Services", 44).dependent = false
|
||||
entry({"admin", "services", "filebrowser"}, cbi("filebrowser/settings"),
|
||||
_("File Browser"), 2).dependent = true
|
||||
|
||||
entry({"admin", "services", "filebrowser", "check"}, call("action_check")).leaf =
|
||||
true
|
||||
entry({"admin", "services", "filebrowser", "download"}, call("action_download")).leaf =
|
||||
true
|
||||
entry({"admin", "services", "filebrowser", "status"}, call("act_status")).leaf =
|
||||
true
|
||||
entry({"admin", "services", "filebrowser", "get_log"}, call("get_log")).leaf =
|
||||
true
|
||||
entry({"admin", "services", "filebrowser", "clear_log"}, call("clear_log")).leaf =
|
||||
true
|
||||
end
|
||||
|
||||
local function http_write_json(content)
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(content or {code = 1})
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e = {}
|
||||
e.status = luci.sys.call("ps -w | grep -v grep | grep 'filebrowser -a' >/dev/null") == 0
|
||||
http_write_json(e)
|
||||
end
|
||||
|
||||
function action_check()
|
||||
local json = api.to_check()
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function action_download()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = api.to_extract(http.formvalue("file"))
|
||||
elseif task == "move" then
|
||||
json = api.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = api.to_download(http.formvalue("url"))
|
||||
end
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function get_log()
|
||||
luci.http.write(luci.sys.exec("[ -f '/var/log/filebrowser.log' ] && cat /var/log/filebrowser.log"))
|
||||
end
|
||||
function clear_log() luci.sys.call("echo '' > /var/log/filebrowser.log") end
|
||||
module("luci.controller.filebrowser", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/filebrowser") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "nas"}, firstchild(), _("NAS") , 45).dependent = false
|
||||
local page
|
||||
page = entry({"admin", "nas", "filebrowser"}, cbi("filebrowser"), _("文件管理器"), 100)
|
||||
page.dependent = true
|
||||
entry({"admin","nas","filebrowser","status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running=luci.sys.call("pgrep filebrowser >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
m = Map("filebrowser", translate("文件管理器"), translate("FileBrowser是一个基于Go的在线文件管理器,助您方便的管理设备上的文件。"))
|
||||
|
||||
m:section(SimpleSection).template = "filebrowser/filebrowser_status"
|
||||
|
||||
s = m:section(TypedSection, "filebrowser")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
enable = s:option(Flag, "enabled", translate("启用"))
|
||||
enable.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "addr_type", translate("监听地址"))
|
||||
o:value("local", translate("监听本机地址"))
|
||||
o:value("lan", translate("监听局域网地址"))
|
||||
o:value("wan", translate("监听全部地址"))
|
||||
o.default = "lan"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "port", translate("监听端口"))
|
||||
o.placeholder = 8989
|
||||
o.default = 8989
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "root_dir", translate("开放目录"))
|
||||
o.placeholder = "/"
|
||||
o.default = "/"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "db_dir", translate("数据库目录"))
|
||||
o.placeholder = "/etc"
|
||||
o.default = "/etc"
|
||||
o.rmempty = false
|
||||
o.description = translate("普通用户请勿随意更改")
|
||||
|
||||
o = s:option(Value, "db_name", translate("数据库名"))
|
||||
o.placeholder = "filebrowser.db"
|
||||
o.default = "filebrowser.db"
|
||||
o.rmempty = false
|
||||
o.description = translate("普通用户请勿随意更改")
|
||||
|
||||
return m
|
||||
@@ -1,338 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
|
||||
module("luci.model.cbi.filebrowser.api", package.seeall)
|
||||
|
||||
local appname = "filebrowser"
|
||||
local api_url =
|
||||
"https://api.github.com/repos/filebrowser/filebrowser/releases/latest"
|
||||
|
||||
local wget = "/usr/bin/wget"
|
||||
local wget_args = {
|
||||
"--no-check-certificate", "--quiet", "--timeout=10", "--tries=2"
|
||||
}
|
||||
local command_timeout = 300
|
||||
|
||||
local LEDE_BOARD = nil
|
||||
local DISTRIB_TARGET = nil
|
||||
|
||||
function uci_get_type(type, config, default)
|
||||
value = uci:get_first(appname, type, config, default) or sys.exec(
|
||||
"echo -n `uci -q get " .. appname .. ".@" .. type .. "[0]." ..
|
||||
config .. "`")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local function _unpack(t, i)
|
||||
i = i or 1
|
||||
if t[i] ~= nil then return t[i], _unpack(t, i + 1) end
|
||||
end
|
||||
|
||||
local function exec(cmd, args, writer, timeout)
|
||||
local os = require "os"
|
||||
local nixio = require "nixio"
|
||||
|
||||
local fdi, fdo = nixio.pipe()
|
||||
local pid = nixio.fork()
|
||||
|
||||
if pid > 0 then
|
||||
fdo:close()
|
||||
|
||||
if writer or timeout then
|
||||
local starttime = os.time()
|
||||
while true do
|
||||
if timeout and os.difftime(os.time(), starttime) >= timeout then
|
||||
nixio.kill(pid, nixio.const.SIGTERM)
|
||||
return 1
|
||||
end
|
||||
|
||||
if writer then
|
||||
local buffer = fdi:read(2048)
|
||||
if buffer and #buffer > 0 then
|
||||
writer(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local wpid, stat, code = nixio.waitpid(pid, "nohang")
|
||||
|
||||
if wpid and stat == "exited" then return code end
|
||||
|
||||
if not writer and timeout then nixio.nanosleep(1) end
|
||||
end
|
||||
else
|
||||
local wpid, stat, code = nixio.waitpid(pid)
|
||||
return wpid and stat == "exited" and code
|
||||
end
|
||||
elseif pid == 0 then
|
||||
nixio.dup(fdo, nixio.stdout)
|
||||
fdi:close()
|
||||
fdo:close()
|
||||
nixio.exece(cmd, args, nil)
|
||||
nixio.stdout:close()
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
|
||||
local function compare_versions(ver1, comp, ver2)
|
||||
local table = table
|
||||
|
||||
local av1 = util.split(ver1, "[%.%-]", nil, true)
|
||||
local av2 = util.split(ver2, "[%.%-]", nil, true)
|
||||
|
||||
local max = table.getn(av1)
|
||||
local n2 = table.getn(av2)
|
||||
if (max < n2) then max = n2 end
|
||||
|
||||
for i = 1, max, 1 do
|
||||
local s1 = av1[i] or ""
|
||||
local s2 = av2[i] or ""
|
||||
|
||||
if comp == "~=" and (s1 ~= s2) then return true end
|
||||
if (comp == "<" or comp == "<=") and (s1 < s2) then return true end
|
||||
if (comp == ">" or comp == ">=") and (s1 > s2) then return true end
|
||||
if (s1 ~= s2) then return false end
|
||||
end
|
||||
|
||||
return not (comp == "<" or comp == ">")
|
||||
end
|
||||
|
||||
local function auto_get_arch()
|
||||
local arch = nixio.uname().machine or ""
|
||||
if fs.access("/usr/lib/os-release") then
|
||||
LEDE_BOARD = sys.exec(
|
||||
"echo -n `grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}'`")
|
||||
end
|
||||
if fs.access("/etc/openwrt_release") then
|
||||
DISTRIB_TARGET = sys.exec(
|
||||
"echo -n `grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}'`")
|
||||
end
|
||||
|
||||
if arch == "mips" then
|
||||
if LEDE_BOARD and LEDE_BOARD ~= "" then
|
||||
if string.match(LEDE_BOARD, "ramips") == "ramips" then
|
||||
arch = "ramips"
|
||||
else
|
||||
arch = sys.exec("echo '" .. LEDE_BOARD ..
|
||||
"' | grep -oE 'ramips|ar71xx'")
|
||||
end
|
||||
elseif DISTRIB_TARGET and DISTRIB_TARGET ~= "" then
|
||||
if string.match(DISTRIB_TARGET, "ramips") == "ramips" then
|
||||
arch = "ramips"
|
||||
else
|
||||
arch = sys.exec("echo '" .. DISTRIB_TARGET ..
|
||||
"' | grep -oE 'ramips|ar71xx'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return util.trim(arch)
|
||||
end
|
||||
|
||||
local function get_file_info(arch)
|
||||
local file_tree = ""
|
||||
local sub_version = ""
|
||||
|
||||
if arch == "x86_64" then
|
||||
file_tree = "amd64"
|
||||
elseif arch == "aarch64" then
|
||||
file_tree = "arm64"
|
||||
elseif arch == "ramips" then
|
||||
file_tree = "mipsle"
|
||||
elseif arch == "ar71xx" then
|
||||
file_tree = "mips"
|
||||
elseif arch:match("^i[%d]86$") then
|
||||
file_tree = "386"
|
||||
elseif arch:match("^armv[5-8]") then
|
||||
file_tree = "armv"
|
||||
sub_version = arch:match("[5-8]")
|
||||
if LEDE_BOARD and string.match(LEDE_BOARD, "bcm53xx") == "bcm53xx" then
|
||||
sub_version = "5"
|
||||
elseif DISTRIB_TARGET and string.match(DISTRIB_TARGET, "bcm53xx") ==
|
||||
"bcm53xx" then
|
||||
sub_version = "5"
|
||||
end
|
||||
sub_version = "5"
|
||||
end
|
||||
|
||||
return file_tree, sub_version
|
||||
end
|
||||
|
||||
local function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local output = {}
|
||||
-- exec(wget, { "-O-", url, _unpack(wget_args) },
|
||||
-- function(chunk) output[#output + 1] = chunk end)
|
||||
-- local json_content = util.trim(table.concat(output))
|
||||
|
||||
local json_content = luci.sys.exec(wget ..
|
||||
" --no-check-certificate --timeout=10 -t 1 -O- " ..
|
||||
url)
|
||||
|
||||
if json_content == "" then return {} end
|
||||
|
||||
return jsonc.parse(json_content) or {}
|
||||
end
|
||||
|
||||
function get_version() return uci_get_type("global", "version", "0") end
|
||||
|
||||
function to_check(arch)
|
||||
if not arch or arch == "" then arch = auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate(
|
||||
"Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
local json = get_api_json(api_url)
|
||||
|
||||
if json.tag_name == nil then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Get remote version info failed.")
|
||||
}
|
||||
end
|
||||
|
||||
local remote_version = json.tag_name:match("[^v]+")
|
||||
|
||||
local needs_update = compare_versions(get_version(), "<", remote_version)
|
||||
local html_url, download_url
|
||||
|
||||
if needs_update then
|
||||
html_url = json.html_url
|
||||
for _, v in ipairs(json.assets) do
|
||||
if v.name and v.name:match("linux%-" .. file_tree .. sub_version) then
|
||||
download_url = v.browser_download_url
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needs_update and not download_url then
|
||||
return {
|
||||
code = 1,
|
||||
version = remote_version,
|
||||
html_url = html_url,
|
||||
error = i18n.translate(
|
||||
"New version found, but failed to get new version download url.")
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
update = needs_update,
|
||||
version = remote_version,
|
||||
url = {html = html_url, download = download_url}
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(url)
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/filebrowser_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec(
|
||||
"mktemp -u -t filebrowser_download.XXXXXX"))
|
||||
|
||||
local result = exec(wget, {"-O", tmp_file, url, _unpack(wget_args)}, nil,
|
||||
command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/filebrowser_extract.*")
|
||||
local tmp_dir = util.trim(util.exec(
|
||||
"mktemp -d -t filebrowser_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
exec("/bin/tar", {"-C", tmp_dir, "-zxvf", file},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
exec("/bin/rm", {"-f", file})
|
||||
|
||||
if not new_file then
|
||||
for _, f in pairs(files) do
|
||||
if f:match("filebrowser") then
|
||||
new_file = tmp_dir .. "/" .. util.trim(f)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not new_file then
|
||||
exec("/bin/rm", {"-rf", tmp_dir})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't find client in file: %s", file)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = new_file}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
sys.call("/bin/rm -rf /tmp/filebrowser_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
local executable_directory =
|
||||
uci_get_type("global", "executable_directory", "/tmp")
|
||||
luci.sys.exec("mkdir -p " .. executable_directory)
|
||||
local client_path = executable_directory .. "/" .. appname
|
||||
local client_path_bak
|
||||
|
||||
if fs.access(client_path) then
|
||||
client_path_bak = "/tmp/" .. appname .. ".bak"
|
||||
exec("/bin/mv", {"-f", client_path, client_path_bak})
|
||||
end
|
||||
|
||||
local result = exec("/bin/mv", {"-f", file, client_path}, nil,
|
||||
command_timeout) == 0
|
||||
|
||||
if not result or not fs.access(client_path) then
|
||||
if client_path_bak then
|
||||
exec("/bin/mv", {"-f", client_path_bak, client_path})
|
||||
end
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s",
|
||||
client_path)
|
||||
}
|
||||
end
|
||||
|
||||
exec("/bin/chmod", {"755", client_path})
|
||||
|
||||
if client_path_bak then exec("/bin/rm", {"-f", client_path_bak}) end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/filebrowser_extract.*")
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@@ -1,59 +0,0 @@
|
||||
m = Map("filebrowser", translate("FileBrowser"), translate(
|
||||
"File explorer is software that creates your own cloud that you can install on a server, point it to a path, and then access your files through a beautiful web interface. You have many features available!"))
|
||||
m:append(Template("filebrowser/status"))
|
||||
|
||||
s = m:section(TypedSection, "global", translate("Global Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "address", translate("Listen address"))
|
||||
o.default = "0.0.0.0"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "port", translate("Listen port"))
|
||||
o.datatype = "port"
|
||||
o.default = 8088
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "database", translate("Database path"))
|
||||
o.default = "/etc/filebrowser.db"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "username", translate("Initial username"))
|
||||
o.default = "admin"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "password", translate("Initial password"))
|
||||
o.default = "admin"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "ssl_cert", translate("SSL cert"))
|
||||
o.default = ""
|
||||
|
||||
o = s:option(Value, "ssl_key", translate("SSL key"))
|
||||
o.default = ""
|
||||
|
||||
o = s:option(Value, "root_path", translate("Root path"), translate(
|
||||
"Point to a path to access your files in the web interface, default is /root"))
|
||||
o.default = "/root"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "executable_directory", translate("Executable directory"),
|
||||
translate(
|
||||
"The file size is large, requiring at least 32M space. It is recommended to insert a usb flash drive or hard disk, or use it in the tmp directory<br />For example, /mnt/sda1<br />For example, /tmp"))
|
||||
o.default = "/tmp"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Button, "_download", translate("Manually download"), translate(
|
||||
"Make sure you have enough space. <br /><font style='color:red'>Be sure to fill out the executable storage directory the first time you run it, and then save the application. Then manually download, otherwise can not use!</font>"))
|
||||
o.template = "filebrowser/download"
|
||||
o.inputstyle = "apply"
|
||||
o.btnclick = "downloadClick(this);"
|
||||
o.id = "download_btn"
|
||||
|
||||
m:append(Template("filebrowser/log"))
|
||||
|
||||
return m
|
||||
@@ -1,169 +0,0 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var msgInfo;
|
||||
|
||||
var tokenStr = '<%=token%>';
|
||||
var clickToDownloadText = '<%:Click to download%>';
|
||||
var inProgressText = '<%:Downloading...%>';
|
||||
var downloadInProgressNotice = '<%:Download, are you sure to close?%>';
|
||||
var downloadSuccessText = '<%:Download successful%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
|
||||
function addPageNotice() {
|
||||
window.onbeforeunload = function(e) {
|
||||
e.returnValue = downloadInProgressNotice;
|
||||
return downloadInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess(btn) {
|
||||
alert(downloadSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = downloadSuccessText;
|
||||
btn.placeholder = downloadSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = btn.placeholder;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function doAjaxGet(url, data, onResult) {
|
||||
new XHR().get(url, data, function(_, json) {
|
||||
var resultJson = json || {
|
||||
'code': 1,
|
||||
'error': unexpectedErrorText
|
||||
};
|
||||
|
||||
if (typeof onResult === 'function') {
|
||||
onResult(resultJson);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function downloadClick(btn) {
|
||||
if (msgInfo === undefined) {
|
||||
checkUpdate(btn);
|
||||
} else {
|
||||
doDownload(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
doAjaxGet('<%=dsp.build_url("admin/services/filebrowser/check")%>/', {
|
||||
token: tokenStr
|
||||
}, function (json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
eval('Info = undefined');
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
eval('Info = json');
|
||||
btn.disabled = false;
|
||||
btn.value = clickToDownloadText;
|
||||
btn.placeholder = clickToDownloadText;
|
||||
}
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.version) {
|
||||
urlNode = '<em style="color:red;"><%:The latest version:%>' + json.version + '</em>';
|
||||
if (json.url && json.url.html) {
|
||||
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
msgInfo = json;
|
||||
});
|
||||
}
|
||||
|
||||
function doDownload(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Downloading...%>';
|
||||
|
||||
addPageNotice();
|
||||
|
||||
var UpdateUrl = '<%=dsp.build_url("admin/services/filebrowser/download")%>';
|
||||
// Download file
|
||||
doAjaxGet(UpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: msgInfo ? msgInfo.url.download : ''
|
||||
}, function (json) {
|
||||
if (json.code) {
|
||||
removePageNotice();
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
btn.value = '<%:Unpacking...%>';
|
||||
|
||||
// Extract file
|
||||
doAjaxGet(UpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file
|
||||
}, function (json) {
|
||||
if (json.code) {
|
||||
removePageNotice();
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
btn.value = '<%:Moving...%>';
|
||||
|
||||
// Move file to target dir
|
||||
doAjaxGet(UpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess(btn);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" type="button"<%=
|
||||
attr("name", cbid) ..
|
||||
attr("id", self.id or cbid) ..
|
||||
attr("value", self.inputtitle or self.title) ..
|
||||
ifattr(self.btnclick, "onclick", self.btnclick) ..
|
||||
ifattr(self.placeholder, "placeholder")
|
||||
%> />
|
||||
<span id="<%=self.id or cbid%>-detail"></span>
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(1, '<%=url([[admin]], [[nas]], [[filebrowser]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('filebrowser_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<font color=green>Filebrowser <%:运行中%></font><input class="cbi-button mar-10" type="button" value="<%:打开管理界面%>" onclick="openClient();" />';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<font color=red>Filebrowser <%:未运行%></font>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function openClient() {
|
||||
var curWwwPath = window.document.location.href;
|
||||
var pathName = window.document.location.pathname;
|
||||
var pos = curWwwPath.indexOf(pathName);
|
||||
var localhostPath = curWwwPath.substring(0, pos);
|
||||
var clientPort = window.document.getElementById("cbid.filebrowser.config.port").value
|
||||
var url = localhostPath + ":" + clientPort;
|
||||
window.open(url)
|
||||
};
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="filebrowser_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
@@ -1,31 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function clear_log(btn) {
|
||||
XHR.get('<%=url([[admin]], [[services]], [[filebrowser]], [[clear_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = "";
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[filebrowser]], [[get_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = x.responseText;
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<fieldset class="cbi-section" id="_log_fieldset">
|
||||
<legend>
|
||||
<%:Logs%>
|
||||
</legend>
|
||||
<input class="cbi-button cbi-input-remove" type="button" onclick="clear_log()" value="<%:Clear logs%>" style="margin-left: 10px;">
|
||||
<textarea id="log_textarea" class="cbi-input-textarea" style="width: calc(100% - 20px); margin: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
|
||||
</fieldset>
|
||||
@@ -1,38 +0,0 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:Running Status%></legend>
|
||||
<fieldset class="cbi-section">
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field" id="_status"><p><span><%:Collecting data...%></span></p></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var _status = document.getElementById('_status');
|
||||
XHR.poll(3,'<%=dsp.build_url("admin/services/filebrowser/status")%>', null,
|
||||
function(x, json) {
|
||||
if (x && x.status == 200) {
|
||||
if (_status)
|
||||
_status.innerHTML = json.status ? '<p><span style="color:green;"><%:RUNNING%></span> <input type="button" class="cbi-button cbi-input-apply" value="<%:Enter interface%>" onclick="openwebui()" /></p>' : '<p><span style="color:red;"><%:NOT RUNNING%></span></p>';
|
||||
}
|
||||
});
|
||||
|
||||
function openwebui(){
|
||||
|
||||
var url = window.location.host;
|
||||
if (url.indexOf(':')) {
|
||||
url = url.split(':')[0];
|
||||
}
|
||||
ssl_cert = "<%=luci.sys.exec("uci get filebrowser.@global[0].ssl_cert"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
ssl_key = "<%=luci.sys.exec("uci get filebrowser.@global[0].ssl_key"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
port = "<%=luci.sys.exec("uci get filebrowser.@global[0].port"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
protocol = 'http';
|
||||
if (ssl_cert !== '' && ssl_key !== '') protocol = 'https';
|
||||
window.open(protocol+'://'+url+':'+port,'target','');
|
||||
}
|
||||
//]]></script>
|
||||
@@ -1,125 +0,0 @@
|
||||
msgid "File Browser"
|
||||
msgstr "文件浏览器"
|
||||
|
||||
msgid "File explorer is software that creates your own cloud that you can install on a server, point it to a path, and then access your files through a beautiful web interface. You have many features available!"
|
||||
msgstr "文件浏览器是一种创建你自己的云的软件,你可以在服务器上安装它,将它指向一个路径,然后通过一个漂亮的web界面访问你的文件。您有许多可用的特性!"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Enter interface"
|
||||
msgstr "进入界面"
|
||||
|
||||
msgid "Global Settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Listen address"
|
||||
msgstr "监听地址"
|
||||
|
||||
msgid "Listen port"
|
||||
msgstr "监听端口"
|
||||
|
||||
msgid "Initial username"
|
||||
msgstr "初始账户"
|
||||
|
||||
msgid "Initial password"
|
||||
msgstr "初始密码"
|
||||
|
||||
msgid "SSL cert"
|
||||
msgstr "SSL 证书"
|
||||
|
||||
msgid "SSL key"
|
||||
msgstr "SSL 私钥"
|
||||
|
||||
msgid "Database path"
|
||||
msgstr "数据库路径"
|
||||
|
||||
msgid "Root path"
|
||||
msgstr "指向路径"
|
||||
|
||||
msgid "Point to a path to access your files in the web interface, default is /root"
|
||||
msgstr "指向一个路径,可在web界面访问你的文件,默认为 /root"
|
||||
|
||||
msgid "Executable directory"
|
||||
msgstr "可执行文件存放目录"
|
||||
|
||||
msgid "The file size is large, requiring at least 32M space. It is recommended to insert a usb flash drive or hard disk, or use it in the tmp directory<br />For example, /mnt/sda1<br />For example, /tmp"
|
||||
msgstr "文件较大,至少需要32M空间。建议插入U盘或硬盘,或放入tmp目录里使用<br />例如:/mnt/sda1<br />例如:/tmp"
|
||||
|
||||
msgid "Manually download"
|
||||
msgstr "手动下载"
|
||||
|
||||
msgid "Make sure you have enough space. <br /><font style='color:red'>Be sure to fill out the executable storage directory the first time you run it, and then save the application. Then manually download, otherwise can not use!</font>"
|
||||
msgstr "请确保具有足够的空间。<br /><font style='color:red'>第一次运行务必填好项目存放目录,然后保存应用。再手动下载,否则无法使用!</font>"
|
||||
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Clear logs"
|
||||
msgstr "清空日志"
|
||||
|
||||
msgid "It is the latest version"
|
||||
msgstr "已是最新版本"
|
||||
|
||||
msgid "Download successful"
|
||||
msgstr "下载成功"
|
||||
|
||||
msgid "Click to download"
|
||||
msgstr "点击下载"
|
||||
|
||||
msgid "Updating..."
|
||||
msgstr "更新中"
|
||||
|
||||
msgid "Unexpected error"
|
||||
msgstr "意外错误"
|
||||
|
||||
msgid "Download, are you sure to close?"
|
||||
msgstr "正在下载,你确认要关闭吗?"
|
||||
|
||||
msgid "Downloading..."
|
||||
msgstr "下载中"
|
||||
|
||||
msgid "Unpacking..."
|
||||
msgstr "解压中"
|
||||
|
||||
msgid "Moving..."
|
||||
msgstr "移动中"
|
||||
|
||||
msgid "The latest version:"
|
||||
msgstr "最新版本:"
|
||||
|
||||
msgid "Can't determine ARCH, or ARCH not supported."
|
||||
msgstr "无法确认ARCH架构,或是不支持。"
|
||||
|
||||
msgid "Get remote version info failed."
|
||||
msgstr "获取远程版本信息失败。"
|
||||
|
||||
msgid "New version found, but failed to get new version download url."
|
||||
msgstr "发现新版本,但未能获得新版本的下载地址。"
|
||||
|
||||
msgid "Download url is required."
|
||||
msgstr "请指定下载地址。"
|
||||
|
||||
msgid "File download failed or timed out: %s"
|
||||
msgstr "文件下载失败或超时:%s"
|
||||
|
||||
msgid "File path required."
|
||||
msgstr "请指定文件路径。"
|
||||
|
||||
msgid "Can't find client in file: %s"
|
||||
msgstr "无法在文件中找到客户端:%s"
|
||||
|
||||
msgid "Client file is required."
|
||||
msgstr "请指定客户端文件。"
|
||||
|
||||
msgid "The client file is not suitable for current device."
|
||||
msgstr "客户端文件不适合当前设备。"
|
||||
|
||||
msgid "Can't move new file to path: %s"
|
||||
msgstr "无法移动新文件到:%s"
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
config global
|
||||
option address '0.0.0.0'
|
||||
option port '8088'
|
||||
option database '/etc/filebrowser.db'
|
||||
option username 'admin'
|
||||
option password 'admin'
|
||||
option ssl_cert ''
|
||||
option ssl_key ''
|
||||
option root_path '/root'
|
||||
option executable_directory '/tmp'
|
||||
option enable '0'
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
# Improve by xiaozhuai <xiaozhuai7@gmail.com>
|
||||
|
||||
START=99
|
||||
|
||||
LOG_PATH="/var/log/filebrowser.log"
|
||||
|
||||
echolog() {
|
||||
echo -e "$(date "+%Y-%m-%d %H:%M:%S"): $1" >> $LOG_PATH
|
||||
}
|
||||
|
||||
config_t_get() {
|
||||
local index=0
|
||||
[ -n "$4" ] && index=$4
|
||||
local ret=$(uci get filebrowser.@$1[$index].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
start() {
|
||||
ENABLED=$(config_t_get global enable 0)
|
||||
[ "$ENABLED" = "0" ] && return
|
||||
ADDRESS=$(config_t_get global address 0.0.0.0)
|
||||
PORT=$(config_t_get global port 8088)
|
||||
DATABASE=$(config_t_get global database /etc/filebrowser.db)
|
||||
USERNAME=$(config_t_get global username admin)
|
||||
PASSWORD=$(config_t_get global password admin)
|
||||
SSL_CERT=$(config_t_get global ssl_cert)
|
||||
SSL_KEY=$(config_t_get global ssl_key)
|
||||
ROOT_PATH=$(config_t_get global root_path /root)
|
||||
executable_directory=$(config_t_get global executable_directory /tmp)
|
||||
[ ! -f "$executable_directory/filebrowser" ] && echolog "$executable_directory/filebrowser not exists, please download first" && exit
|
||||
|
||||
SSL_PARAMS=""
|
||||
[ -n "$SSL_CERT" ] && [ -n "$SSL_KEY" ] && SSL_PARAMS="-t $SSL_CERT -k $SSL_KEY"
|
||||
PASSWORD="$($executable_directory/filebrowser hash "$PASSWORD")"
|
||||
$executable_directory/filebrowser -a $ADDRESS -p $PORT -r $ROOT_PATH -d "$DATABASE" --username $USERNAME --password $PASSWORD $SSL_PARAMS -l $LOG_PATH >/dev/null 2>&1 &
|
||||
}
|
||||
|
||||
stop() {
|
||||
ps -w | grep -v "grep" | grep "$executable_directory/filebrowser -a" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
rm -rf $LOG_PATH
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
}
|
||||
Regular → Executable
+11
-11
@@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@filebrowser[-1]
|
||||
add ucitrack filebrowser
|
||||
set ucitrack.@filebrowser[-1].init=filebrowser
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@filebrowser[-1]
|
||||
add ucitrack filebrowser
|
||||
set ucitrack.@filebrowser[-1].init=filebrowser
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"luci-app-filebrowser": {
|
||||
"description": "Grant UCI access for luci-app-filebrowser",
|
||||
"read": {
|
||||
"uci": [ "filebrowser" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "filebrowser" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ function index()
|
||||
local page
|
||||
page = entry({"admin", "services", "gost"}, cbi("gost"), _("Gost"), 100)
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-gost" }
|
||||
entry({"admin", "services", "gost", "status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
zh_Hans
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"luci-app-gost": {
|
||||
"description": "Grant UCI access for luci-app-gost",
|
||||
"read": {
|
||||
"uci": [ "gost" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "gost" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -34,7 +34,7 @@ require (
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/sing-tun v0.4.0-rc.3
|
||||
github.com/sagernet/sing-tun v0.4.0-rc.3.0.20241014141023-07278fb4705b
|
||||
github.com/sagernet/sing-vmess v0.1.12
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
|
||||
github.com/sagernet/utls v1.6.7
|
||||
|
||||
+2
-2
@@ -129,8 +129,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wK
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
||||
github.com/sagernet/sing-tun v0.4.0-rc.3 h1:W/Odc87dGXkRhwRo2jhsKYHypNbajIcsGlIzDatmMKA=
|
||||
github.com/sagernet/sing-tun v0.4.0-rc.3/go.mod h1:+lQdWhqD4atzrCgRhoyrxBCg1OBru/hAv2BT3kdgmGM=
|
||||
github.com/sagernet/sing-tun v0.4.0-rc.3.0.20241014141023-07278fb4705b h1:a2VWOxv7uvIThhJyW6bB+D+bciLSkkqzq4bC4yg3U0g=
|
||||
github.com/sagernet/sing-tun v0.4.0-rc.3.0.20241014141023-07278fb4705b/go.mod h1:+lQdWhqD4atzrCgRhoyrxBCg1OBru/hAv2BT3kdgmGM=
|
||||
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
|
||||
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
|
||||
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ssr-plus
|
||||
PKG_VERSION:=188
|
||||
PKG_RELEASE:=7
|
||||
PKG_RELEASE:=8
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \
|
||||
|
||||
@@ -109,6 +109,10 @@ o:depends("shunt_dns_mode", "2")
|
||||
o.rmempty = false
|
||||
o.default = "0"
|
||||
|
||||
o = s:option(Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"))
|
||||
o.rmempty = false
|
||||
o.default = "1"
|
||||
|
||||
o = s:option(Flag, "adblock", translate("Enable adblock"))
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
@@ -927,7 +927,6 @@ if is_finded("xray") then
|
||||
o:value(v, translate(v))
|
||||
end
|
||||
o.rmempty = true
|
||||
o:depends("xtls", true)
|
||||
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "tcp", tls = true})
|
||||
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "tcp", reality = true})
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ o.description = translate("Custom DNS Server for mosdns")
|
||||
o = s:option(Flag, "mosdns_ipv6", translate("Disable IPv6 in MOSDNS query mode"))
|
||||
o:depends("pdnsd_enable", "3")
|
||||
o.rmempty = false
|
||||
o.default = "0"
|
||||
o.default = "1"
|
||||
|
||||
if is_finded("chinadns-ng") then
|
||||
o = s:option(Value, "chinadns_forward", translate("Domestic DNS Server"))
|
||||
|
||||
@@ -459,6 +459,12 @@ msgstr "切换检查超时时间(秒)"
|
||||
msgid "Check Try Count"
|
||||
msgstr "切换检查重试次数"
|
||||
|
||||
msgid "Apple domains optimization"
|
||||
msgstr "Apple 域名解析优化"
|
||||
|
||||
msgid "For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"
|
||||
msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址"
|
||||
|
||||
msgid "Enable adblock"
|
||||
msgstr "启用广告屏蔽"
|
||||
|
||||
|
||||
@@ -246,6 +246,12 @@ start_dns() {
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$(uci_get_by_type global apple_optimization 1)" == "1" ]; then
|
||||
echolog "Apple 域名中国大陆 CDN 的 优化规则正在加载。"
|
||||
cp -f /etc/ssrplus/applechina.conf $TMP_DNSMASQ_PATH/
|
||||
echolog "Apple 域名中国大陆 CDN 的 优化规则加载完毕。"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_service_file() { #1-server.type 2-cfgname 3-file_path
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
server=/a1.mzstatic.com/114.114.114.114
|
||||
server=/a2.mzstatic.com/114.114.114.114
|
||||
server=/a3.mzstatic.com/114.114.114.114
|
||||
server=/a4.mzstatic.com/114.114.114.114
|
||||
server=/a5.mzstatic.com/114.114.114.114
|
||||
server=/adcdownload.apple.com.akadns.net/114.114.114.114
|
||||
server=/adcdownload.apple.com/114.114.114.114
|
||||
server=/amp-api-updates.apps.apple.com/114.114.114.114
|
||||
server=/amp-api.media.apple.com/114.114.114.114
|
||||
server=/api-p-ap-c.smoot.apple.com/114.114.114.114
|
||||
server=/api-p-ap-d.smoot.apple.com/114.114.114.114
|
||||
server=/api-p-ap-e.smoot.apple.com/114.114.114.114
|
||||
server=/app-site-association.cdn-apple.com/114.114.114.114
|
||||
server=/appldnld.apple.com/114.114.114.114
|
||||
server=/appldnld.g.aaplimg.com/114.114.114.114
|
||||
server=/appleid.cdn-apple.com/114.114.114.114
|
||||
server=/apps.apple.com/114.114.114.114
|
||||
server=/apps.mzstatic.com/114.114.114.114
|
||||
server=/bag-cdn.itunes-apple.com.akadns.net/114.114.114.114
|
||||
server=/cdn-cn1.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn-cn2.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn-cn3.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn-cn4.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn1.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn2.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn3.apple-mapkit.com/114.114.114.114
|
||||
server=/cdn4.apple-mapkit.com/114.114.114.114
|
||||
server=/cds-cdn.v.aaplimg.com/114.114.114.114
|
||||
server=/cds.apple.com.akadns.net/114.114.114.114
|
||||
server=/cds.apple.com/114.114.114.114
|
||||
server=/cdsassets.apple.com/114.114.114.114
|
||||
server=/cl1-cdn.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/cl1.apple.com/114.114.114.114
|
||||
server=/cl2-cn.apple.com/114.114.114.114
|
||||
server=/cl2.apple.com/114.114.114.114
|
||||
server=/cl3-cdn.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/cl3.apple.com/114.114.114.114
|
||||
server=/cl4-cdn.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/cl4-cn.apple.com/114.114.114.114
|
||||
server=/cl4.apple.com/114.114.114.114
|
||||
server=/cl5-cdn.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/cl5.apple.com/114.114.114.114
|
||||
server=/clientflow.apple.com.akadns.net/114.114.114.114
|
||||
server=/clientflow.apple.com/114.114.114.114
|
||||
server=/cn-smp-paymentservices.apple.com/114.114.114.114
|
||||
server=/configuration.apple.com.akadns.net/114.114.114.114
|
||||
server=/configuration.apple.com/114.114.114.114
|
||||
server=/crl.apple.com/114.114.114.114
|
||||
server=/cstat.apple.com/114.114.114.114
|
||||
server=/cstat.cdn-apple.com/114.114.114.114
|
||||
server=/dd-cdn.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/dejavu.apple.com/114.114.114.114
|
||||
server=/devstreaming-cdn.apple.com/114.114.114.114
|
||||
server=/download.developer.apple.com/114.114.114.114
|
||||
server=/experiments.apple.com/114.114.114.114
|
||||
server=/gs-loc-cn.apple.com/114.114.114.114
|
||||
server=/gs-loc.apple.com/114.114.114.114
|
||||
server=/gsp10-ssl-cn.ls.apple.com/114.114.114.114
|
||||
server=/gsp12-cn.ls.apple.com/114.114.114.114
|
||||
server=/gsp13-cn.ls.apple.com/114.114.114.114
|
||||
server=/gsp4-cn.ls.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114
|
||||
server=/gsp4-cn.ls.apple.com.edgekey.net/114.114.114.114
|
||||
server=/gsp4-cn.ls.apple.com/114.114.114.114
|
||||
server=/gsp5-cn.ls.apple.com/114.114.114.114
|
||||
server=/gsp85-cn-ssl.ls.apple.com/114.114.114.114
|
||||
server=/gspe19-2-cn-ssl.ls-apple.com.akadns.net/114.114.114.114
|
||||
server=/gspe19-2-cn-ssl.ls.apple.com/114.114.114.114
|
||||
server=/gspe19-cn-ssl.ls.apple.com/114.114.114.114
|
||||
server=/gspe19-cn.ls-apple.com.akadns.net/114.114.114.114
|
||||
server=/gspe19-cn.ls.apple.com/114.114.114.114
|
||||
server=/gspe21-ssl.ls.apple.com/114.114.114.114
|
||||
server=/gspe21.ls.apple.com/114.114.114.114
|
||||
server=/gspe35-ssl.ls.apple.com/114.114.114.114
|
||||
server=/gspe79-cn-ssl.ls.apple.com/114.114.114.114
|
||||
server=/guzzoni-apple-com.v.aaplimg.com/114.114.114.114
|
||||
server=/guzzoni.apple.com/114.114.114.114
|
||||
server=/guzzoni.smoot.apple.com/114.114.114.114
|
||||
server=/iadsdk.apple.com/114.114.114.114
|
||||
server=/icloud-cdn.icloud.com.akadns.net/114.114.114.114
|
||||
server=/icloud.cdn-apple.com/114.114.114.114
|
||||
server=/images.apple.com.akadns.net/114.114.114.114
|
||||
server=/images.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114
|
||||
server=/images.apple.com/114.114.114.114
|
||||
server=/init-kt.apple.com/114.114.114.114
|
||||
server=/init-p01md-lb.push-apple.com.akadns.net/114.114.114.114
|
||||
server=/init-p01md.apple.com/114.114.114.114
|
||||
server=/init-p01st-lb.push-apple.com.akadns.net/114.114.114.114
|
||||
server=/init-p01st.push.apple.com/114.114.114.114
|
||||
server=/init-s01st-lb.push-apple.com.akadns.net/114.114.114.114
|
||||
server=/init-s01st.push.apple.com/114.114.114.114
|
||||
server=/init.ess.apple.com/114.114.114.114
|
||||
server=/iosapps.itunes.g.aaplimg.com/114.114.114.114
|
||||
server=/ipcdn.apple.com/114.114.114.114
|
||||
server=/iphone-ld.apple.com/114.114.114.114
|
||||
server=/iphone-ld.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/is-ssl.mzstatic.com-cn-lb.itunes-apple.com.akadns.net/114.114.114.114
|
||||
server=/is1-ssl.mzstatic.com/114.114.114.114
|
||||
server=/is1.mzstatic.com/114.114.114.114
|
||||
server=/is2-ssl.mzstatic.com/114.114.114.114
|
||||
server=/is2.mzstatic.com/114.114.114.114
|
||||
server=/is3-ssl.mzstatic.com/114.114.114.114
|
||||
server=/is3.mzstatic.com/114.114.114.114
|
||||
server=/is4-ssl.mzstatic.com/114.114.114.114
|
||||
server=/is4.mzstatic.com/114.114.114.114
|
||||
server=/is5-ssl.mzstatic.com/114.114.114.114
|
||||
server=/is5.mzstatic.com/114.114.114.114
|
||||
server=/itunes-apple.com.akadns.net/114.114.114.114
|
||||
server=/itunes.apple.com/114.114.114.114
|
||||
server=/itunesconnect.apple.com/114.114.114.114
|
||||
server=/mesu-cdn.apple.com.akadns.net/114.114.114.114
|
||||
server=/mesu-china.apple.com.akadns.net/114.114.114.114
|
||||
server=/mesu.apple.com/114.114.114.114
|
||||
server=/ml.cdn-apple.com/114.114.114.114
|
||||
server=/music.apple.com/114.114.114.114
|
||||
server=/ocsp-lb.apple.com.akadns.net/114.114.114.114
|
||||
server=/ocsp.apple.com/114.114.114.114
|
||||
server=/ocsp2-lb.apple.com.akadns.net/114.114.114.114
|
||||
server=/ocsp2.apple.com/114.114.114.114
|
||||
server=/oscdn.apple.com/114.114.114.114
|
||||
server=/oscdn.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/osxapps.itunes.g.aaplimg.com/114.114.114.114
|
||||
server=/pancake.apple.com/114.114.114.114
|
||||
server=/pancake.cdn-apple.com.akadns.net/114.114.114.114
|
||||
server=/pba0.apple.com/114.114.114.114
|
||||
server=/probe.siri.apple.com/114.114.114.114
|
||||
server=/prod-support.apple-support.akadns.net/114.114.114.114
|
||||
server=/publicassets.cdn-apple.com/114.114.114.114
|
||||
server=/reserve-prime.apple.com/114.114.114.114
|
||||
server=/s.mzstatic.com/114.114.114.114
|
||||
server=/seed-sequoia.siri.apple.com/114.114.114.114
|
||||
server=/seed-swallow.siri.apple.com/114.114.114.114
|
||||
server=/seed.siri.apple.com/114.114.114.114
|
||||
server=/sequoia.apple.com/114.114.114.114
|
||||
server=/sh-pod2-smp-device.apple.com/114.114.114.114
|
||||
server=/shazam-insights.cdn-apple.com/114.114.114.114
|
||||
server=/smp-device-content.apple.com/114.114.114.114
|
||||
server=/static.gc.apple.com/114.114.114.114
|
||||
server=/stocks-sparkline-lb.apple.com.akadns.net/114.114.114.114
|
||||
server=/stocks-sparkline.apple.com/114.114.114.114
|
||||
server=/store.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114
|
||||
server=/store.apple.com.edgekey.net/114.114.114.114
|
||||
server=/store.apple.com/114.114.114.114
|
||||
server=/store.storeimages.apple.com.akadns.net/114.114.114.114
|
||||
server=/store.storeimages.cdn-apple.com/114.114.114.114
|
||||
server=/support-china.apple-support.akadns.net/114.114.114.114
|
||||
server=/support.apple.com/114.114.114.114
|
||||
server=/swallow-apple-com.v.aaplimg.com/114.114.114.114
|
||||
server=/swallow.apple.com/114.114.114.114
|
||||
server=/swcatalog-cdn.apple.com.akadns.net/114.114.114.114
|
||||
server=/swcatalog.apple.com/114.114.114.114
|
||||
server=/swcdn.apple.com/114.114.114.114
|
||||
server=/swcdn.g.aaplimg.com/114.114.114.114
|
||||
server=/swdist.apple.com.akadns.net/114.114.114.114
|
||||
server=/swdist.apple.com/114.114.114.114
|
||||
server=/swscan-cdn.apple.com.akadns.net/114.114.114.114
|
||||
server=/swscan.apple.com/114.114.114.114
|
||||
server=/sylvan.apple.com/114.114.114.114
|
||||
server=/tj-pod1-smp-device.apple.com/114.114.114.114
|
||||
server=/updates-http.cdn-apple.com.akadns.net/114.114.114.114
|
||||
server=/updates-http.cdn-apple.com/114.114.114.114
|
||||
server=/updates.cdn-apple.com/114.114.114.114
|
||||
server=/valid.apple.com/114.114.114.114
|
||||
server=/valid.origin-apple.com.akadns.net/114.114.114.114
|
||||
server=/weather-data.apple.com.akadns.net/114.114.114.114
|
||||
server=/weather-data.apple.com/114.114.114.114
|
||||
server=/weather-map.apple.com/114.114.114.114
|
||||
server=/weather-map2.apple.com/114.114.114.114
|
||||
server=/weatherkit.apple.com/114.114.114.114
|
||||
server=/www.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114
|
||||
server=/www.apple.com.edgekey.net/114.114.114.114
|
||||
server=/www.apple.com/114.114.114.114
|
||||
server=/xp.apple.com/114.114.114.114
|
||||
@@ -362,10 +362,9 @@ local function processData(szType, content)
|
||||
result.vmess_id = url.user
|
||||
result.vless_encryption = params.encryption or "none"
|
||||
result.transport = params.type or "tcp"
|
||||
result.tls = (params.security == "tls") and "1" or "0"
|
||||
result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0"
|
||||
result.tls_host = params.sni
|
||||
result.xtls = (params.security == "xtls") and "1" or nil
|
||||
result.tls_flow = (result.tls == "1" or result.xtls == "1" or result.reality == "1") and params.flow or nil
|
||||
result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil
|
||||
result.fingerprint = params.fp
|
||||
result.reality = (params.security == "reality") and "1" or "0"
|
||||
result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=v2ray-core
|
||||
PKG_VERSION:=5.20.0
|
||||
PKG_VERSION:=5.21.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/v2fly/v2ray-core/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=2de8ac3429705f594ca1a75a2a0fca09820938c94e912370902f87bd72680693
|
||||
PKG_HASH:=880a929caff7b72ef9d3b9a3262cec0dff6566c2481989822a6b27fdaaeed975
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -30,13 +30,13 @@ define Download/geosite
|
||||
HASH:=f820556ed3aa02eb7eadba7a3743d7e6df8e9234785d0d82d2d1edce20fe4b3c
|
||||
endef
|
||||
|
||||
GEOSITE_IRAN_VER:=202410070035
|
||||
GEOSITE_IRAN_VER:=202410140035
|
||||
GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER)
|
||||
define Download/geosite-ir
|
||||
URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/
|
||||
URL_FILE:=iran.dat
|
||||
FILE:=$(GEOSITE_IRAN_FILE)
|
||||
HASH:=be31e14b61dc3e98c9ac518686bc932b45aa04dd2f9491d18456417ba28f3b70
|
||||
HASH:=97d1efd7ce4e5318f9f44039f5945a6253d5a42f7f3b432d3da124703d4cda28
|
||||
endef
|
||||
|
||||
define Package/v2ray-geodata/template
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ServiceLib.Common
|
||||
}
|
||||
};
|
||||
|
||||
using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
await using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
downloader.DownloadFileCompleted += (sender, value) =>
|
||||
{
|
||||
if (value.Error != null)
|
||||
@@ -46,12 +46,12 @@ namespace ServiceLib.Common
|
||||
};
|
||||
|
||||
using var cts = new CancellationTokenSource();
|
||||
using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);
|
||||
await using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);
|
||||
using StreamReader reader = new(stream);
|
||||
|
||||
downloadOpt = null;
|
||||
|
||||
return reader.ReadToEnd();
|
||||
return await reader.ReadToEndAsync(cts.Token);
|
||||
}
|
||||
|
||||
public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress<string> progress, int timeout)
|
||||
@@ -72,11 +72,11 @@ namespace ServiceLib.Common
|
||||
}
|
||||
};
|
||||
|
||||
DateTime totalDatetime = DateTime.Now;
|
||||
int totalSecond = 0;
|
||||
var totalDatetime = DateTime.Now;
|
||||
var totalSecond = 0;
|
||||
var hasValue = false;
|
||||
double maxSpeed = 0;
|
||||
using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
await using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
//downloader.DownloadStarted += (sender, value) =>
|
||||
//{
|
||||
// if (progress != null)
|
||||
@@ -86,7 +86,7 @@ namespace ServiceLib.Common
|
||||
//};
|
||||
downloader.DownloadProgressChanged += (sender, value) =>
|
||||
{
|
||||
TimeSpan ts = (DateTime.Now - totalDatetime);
|
||||
var ts = (DateTime.Now - totalDatetime);
|
||||
if (progress != null && ts.Seconds > totalSecond)
|
||||
{
|
||||
hasValue = true;
|
||||
@@ -112,7 +112,7 @@ namespace ServiceLib.Common
|
||||
//progress.Report("......");
|
||||
using var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(timeout * 1000);
|
||||
using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token);
|
||||
await using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token);
|
||||
|
||||
downloadOpt = null;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace ServiceLib.Common
|
||||
|
||||
var progressPercentage = 0;
|
||||
var hasValue = false;
|
||||
using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
await using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
downloader.DownloadStarted += (sender, value) =>
|
||||
{
|
||||
progress?.Report(0);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ServiceLib.Common
|
||||
{
|
||||
try
|
||||
{
|
||||
using FileStream fs = File.Create(fileName);
|
||||
using var fs = File.Create(fileName);
|
||||
using GZipStream input = new(new MemoryStream(content), CompressionMode.Decompress, false);
|
||||
input.CopyTo(fs);
|
||||
}
|
||||
@@ -38,8 +38,8 @@ namespace ServiceLib.Common
|
||||
try
|
||||
{
|
||||
FileInfo fileInfo = new(fileName);
|
||||
using FileStream originalFileStream = fileInfo.OpenRead();
|
||||
using FileStream decompressedFileStream = File.Create(toName != null ? Path.Combine(toPath, toName) : toPath);
|
||||
using var originalFileStream = fileInfo.OpenRead();
|
||||
using var decompressedFileStream = File.Create(toName != null ? Path.Combine(toPath, toName) : toPath);
|
||||
using GZipStream decompressionStream = new(originalFileStream, CompressionMode.Decompress);
|
||||
decompressionStream.CopyTo(decompressedFileStream);
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace ServiceLib.Common
|
||||
return NonExclusiveReadAllText(path, Encoding.Default);
|
||||
}
|
||||
|
||||
public static string NonExclusiveReadAllText(string path, Encoding encoding)
|
||||
private static string NonExclusiveReadAllText(string path, Encoding encoding)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -73,8 +73,8 @@ namespace ServiceLib.Common
|
||||
{
|
||||
try
|
||||
{
|
||||
using ZipArchive archive = ZipFile.OpenRead(fileName);
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
using var archive = ZipFile.OpenRead(fileName);
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
if (entry.Length == 0)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ namespace ServiceLib.Common
|
||||
}
|
||||
try
|
||||
{
|
||||
using ZipArchive archive = ZipFile.OpenRead(fileName);
|
||||
using var archive = ZipFile.OpenRead(fileName);
|
||||
return archive.Entries.Select(entry => entry.FullName).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -149,13 +149,13 @@ namespace ServiceLib.Common
|
||||
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
|
||||
|
||||
// Cache directories before we start copying
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
var dirs = dir.GetDirectories();
|
||||
|
||||
// Create the destination directory
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
// Get the files in the source directory and copy to the destination directory
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
foreach (var file in dir.GetFiles())
|
||||
{
|
||||
if (Utils.IsNotEmpty(ignoredName) && file.Name.Contains(ignoredName))
|
||||
{
|
||||
@@ -165,16 +165,16 @@ namespace ServiceLib.Common
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string targetFilePath = Path.Combine(destinationDir, file.Name);
|
||||
var targetFilePath = Path.Combine(destinationDir, file.Name);
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
|
||||
// If recursive and copying subdirectories, recursively call this method
|
||||
if (recursive)
|
||||
{
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
foreach (var subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||||
var newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir, true, ignoredName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace ServiceLib.Common
|
||||
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = await httpClient.GetAsync(url);
|
||||
var response = await httpClient.GetAsync(url);
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
catch
|
||||
@@ -84,8 +84,8 @@ namespace ServiceLib.Common
|
||||
var total = response.Content.Headers.ContentLength ?? -1L;
|
||||
var canReportProgress = total != -1 && progress != null;
|
||||
|
||||
using var stream = await response.Content.ReadAsStreamAsync(token);
|
||||
using var file = File.Create(fileName);
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(token);
|
||||
await using var file = File.Create(fileName);
|
||||
var totalRead = 0L;
|
||||
var buffer = new byte[1024 * 1024];
|
||||
var progressPercentage = 0;
|
||||
@@ -98,7 +98,7 @@ namespace ServiceLib.Common
|
||||
totalRead += read;
|
||||
|
||||
if (read == 0) break;
|
||||
file.Write(buffer, 0, read);
|
||||
await file.WriteAsync(buffer, 0, read, token);
|
||||
|
||||
if (canReportProgress)
|
||||
{
|
||||
@@ -133,13 +133,13 @@ namespace ServiceLib.Common
|
||||
//var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
|
||||
//var canReportProgress = total != -1 && progress != null;
|
||||
|
||||
using var stream = await response.Content.ReadAsStreamAsync(token);
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(token);
|
||||
var totalRead = 0L;
|
||||
var buffer = new byte[1024 * 64];
|
||||
var isMoreToRead = true;
|
||||
string progressSpeed = string.Empty;
|
||||
DateTime totalDatetime = DateTime.Now;
|
||||
int totalSecond = 0;
|
||||
var progressSpeed = string.Empty;
|
||||
var totalDatetime = DateTime.Now;
|
||||
var totalSecond = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -168,7 +168,7 @@ namespace ServiceLib.Common
|
||||
|
||||
totalRead += read;
|
||||
|
||||
TimeSpan ts = (DateTime.Now - totalDatetime);
|
||||
var ts = (DateTime.Now - totalDatetime);
|
||||
if (progress != null && ts.Seconds > totalSecond)
|
||||
{
|
||||
totalSecond = ts.Seconds;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ServiceLib.Common
|
||||
* http://stackoverflow.com/questions/6266820/working-example-of-createjobobject-setinformationjobobject-pinvoke-in-net
|
||||
*/
|
||||
|
||||
public class Job : IDisposable
|
||||
public sealed class Job : IDisposable
|
||||
{
|
||||
private IntPtr handle = IntPtr.Zero;
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace ServiceLib.Common
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ServiceLib.Common
|
||||
/// <returns></returns>
|
||||
public static string Serialize(object? obj, bool indented = true)
|
||||
{
|
||||
string result = string.Empty;
|
||||
var result = string.Empty;
|
||||
try
|
||||
{
|
||||
if (obj == null)
|
||||
@@ -112,7 +112,7 @@ namespace ServiceLib.Common
|
||||
}
|
||||
try
|
||||
{
|
||||
using FileStream file = File.Create(filePath);
|
||||
using var file = File.Create(filePath);
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ServiceLib.Common
|
||||
public static byte[]? GenQRCode(string? url)
|
||||
{
|
||||
using QRCodeGenerator qrGenerator = new();
|
||||
using QRCodeData qrCodeData = qrGenerator.CreateQrCode(url ?? string.Empty, QRCodeGenerator.ECCLevel.Q);
|
||||
using var qrCodeData = qrGenerator.CreateQrCode(url ?? string.Empty, QRCodeGenerator.ECCLevel.Q);
|
||||
using PngByteQRCode qrCode = new(qrCodeData);
|
||||
return qrCode.GetGraphic(20);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ServiceLib.Common
|
||||
|
||||
private static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)
|
||||
{
|
||||
string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
|
||||
var methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
|
||||
|
||||
var memberProp = typeof(T).GetProperty(propertyName);
|
||||
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
}
|
||||
this.version = version.RemovePrefix('v');
|
||||
|
||||
string[] parts = this.version.Split('.');
|
||||
var parts = this.version.Split('.');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
this.major = int.Parse(parts[0]);
|
||||
this.minor = int.Parse(parts[1]);
|
||||
this.patch = 0;
|
||||
}
|
||||
else if (parts.Length == 3 || parts.Length == 4)
|
||||
else if (parts.Length is 3 or 4)
|
||||
{
|
||||
this.major = int.Parse(parts[0]);
|
||||
this.minor = int.Parse(parts[1]);
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace ServiceLib.Common
|
||||
private SQLiteConnection _db;
|
||||
private SQLiteAsyncConnection _dbAsync;
|
||||
private static readonly object objLock = new();
|
||||
public readonly string _configDB = "guiNDB.db";
|
||||
private readonly string _configDB = "guiNDB.db";
|
||||
|
||||
public SQLiteHelper()
|
||||
{
|
||||
|
||||
@@ -25,21 +25,14 @@ namespace ServiceLib.Common
|
||||
return chars.Contains(s[0]);
|
||||
}
|
||||
|
||||
public static bool IsWhiteSpace(this string value)
|
||||
private static bool IsWhiteSpace(this string value)
|
||||
{
|
||||
foreach (char c in value)
|
||||
{
|
||||
if (char.IsWhiteSpace(c)) continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return value.All(char.IsWhiteSpace);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader)
|
||||
{
|
||||
string? line;
|
||||
while ((line = reader.ReadLine()) != null)
|
||||
while (reader.ReadLine() is { } line)
|
||||
{
|
||||
if (line.IsWhiteSpace()) continue;
|
||||
yield return line;
|
||||
@@ -53,26 +46,12 @@ namespace ServiceLib.Common
|
||||
|
||||
public static string RemovePrefix(this string value, char prefix)
|
||||
{
|
||||
if (value.StartsWith(prefix))
|
||||
{
|
||||
return value.Substring(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return value.StartsWith(prefix) ? value[1..] : value;
|
||||
}
|
||||
|
||||
public static string RemovePrefix(this string value, string prefix)
|
||||
{
|
||||
if (value.StartsWith(prefix))
|
||||
{
|
||||
return value.Substring(prefix.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return value.StartsWith(prefix) ? value[prefix.Length..] : value;
|
||||
}
|
||||
|
||||
public static string UpperFirstChar(this string value)
|
||||
@@ -82,17 +61,12 @@ namespace ServiceLib.Common
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return char.ToUpper(value[0]) + value.Substring(1);
|
||||
return char.ToUpper(value[0]) + value[1..];
|
||||
}
|
||||
|
||||
public static string AppendQuotes(this string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $"\"{value}\"";
|
||||
return string.IsNullOrEmpty(value) ? string.Empty : $"\"{value}\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using CliWrap.Buffered;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
@@ -11,13 +10,12 @@ using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ServiceLib.Common
|
||||
{
|
||||
public class Utils
|
||||
{
|
||||
#region 资源Json操作
|
||||
#region 资源操作
|
||||
|
||||
/// <summary>
|
||||
/// 获取嵌入文本资源
|
||||
@@ -26,12 +24,12 @@ namespace ServiceLib.Common
|
||||
/// <returns></returns>
|
||||
public static string GetEmbedText(string res)
|
||||
{
|
||||
string result = string.Empty;
|
||||
var result = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
using Stream? stream = assembly.GetManifestResourceStream(res);
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
using var stream = assembly.GetManifestResourceStream(res);
|
||||
ArgumentNullException.ThrowIfNull(stream);
|
||||
using StreamReader reader = new(stream);
|
||||
result = reader.ReadToEnd();
|
||||
@@ -51,11 +49,10 @@ namespace ServiceLib.Common
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(res))
|
||||
if (File.Exists(res))
|
||||
{
|
||||
return null;
|
||||
return File.ReadAllText(res);
|
||||
}
|
||||
return File.ReadAllText(res);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -64,14 +61,15 @@ namespace ServiceLib.Common
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion 资源Json操作
|
||||
#endregion 资源操作
|
||||
|
||||
#region 转换函数
|
||||
|
||||
/// <summary>
|
||||
/// List<string>转逗号分隔的字符串
|
||||
/// 转逗号分隔的字符串
|
||||
/// </summary>
|
||||
/// <param name="lst"></param>
|
||||
/// <param name="wrap"></param>
|
||||
/// <returns></returns>
|
||||
public static string List2String(List<string>? lst, bool wrap = false)
|
||||
{
|
||||
@@ -93,35 +91,40 @@ namespace ServiceLib.Common
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
return string.Empty;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逗号分隔的字符串,转List<string>
|
||||
/// 逗号分隔的字符串
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static List<string> String2List(string str)
|
||||
public static List<string>? String2List(string? str)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
str = str.Replace(Environment.NewLine, "");
|
||||
return new List<string>(str.Split(',', StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
return [];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逗号分隔的字符串,先排序后转List<string>
|
||||
/// 逗号分隔的字符串,先排序后转List
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static List<string> String2ListSorted(string str)
|
||||
public static List<string>? String2ListSorted(string str)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -133,8 +136,8 @@ namespace ServiceLib.Common
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
return [];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -146,14 +149,14 @@ namespace ServiceLib.Common
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
||||
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
||||
return Convert.ToBase64String(plainTextBytes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog("Base64Encode", ex);
|
||||
return string.Empty;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -179,30 +182,24 @@ namespace ServiceLib.Common
|
||||
plainText = plainText.PadRight(plainText.Length + 4 - plainText.Length % 4, '=');
|
||||
}
|
||||
|
||||
byte[] data = Convert.FromBase64String(plainText);
|
||||
var data = Convert.FromBase64String(plainText);
|
||||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog("Base64Decode", ex);
|
||||
return string.Empty;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转Int
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static int ToInt(object? obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToInt32(obj ?? string.Empty);
|
||||
}
|
||||
catch //(Exception ex)
|
||||
catch
|
||||
{
|
||||
//SaveLog(ex.Message, ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -213,50 +210,47 @@ namespace ServiceLib.Common
|
||||
{
|
||||
return Convert.ToBoolean(obj);
|
||||
}
|
||||
catch //(Exception ex)
|
||||
catch
|
||||
{
|
||||
//SaveLog(ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToString(object obj)
|
||||
public static string ToString(object? obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
return obj?.ToString() ?? string.Empty;
|
||||
}
|
||||
catch// (Exception ex)
|
||||
catch
|
||||
{
|
||||
//SaveLog(ex.Message, ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// byte 转成 有两位小数点的 方便阅读的数据
|
||||
/// 比如 2.50 MB
|
||||
/// byte 转成 有两位小数点的 方便阅读的数据 比如 2.50 MB
|
||||
/// </summary>
|
||||
/// <param name="amount">bytes</param>
|
||||
/// <param name="result">转换之后的数据</param>
|
||||
/// <param name="unit">单位</param>
|
||||
public static void ToHumanReadable(long amount, out double result, out string unit)
|
||||
private static void ToHumanReadable(long amount, out double result, out string unit)
|
||||
{
|
||||
uint factor = 1024u;
|
||||
var factor = 1024u;
|
||||
//long KBs = amount / factor;
|
||||
long KBs = amount;
|
||||
var KBs = amount;
|
||||
if (KBs > 0)
|
||||
{
|
||||
// multi KB
|
||||
long MBs = KBs / factor;
|
||||
var MBs = KBs / factor;
|
||||
if (MBs > 0)
|
||||
{
|
||||
// multi MB
|
||||
long GBs = MBs / factor;
|
||||
var GBs = MBs / factor;
|
||||
if (GBs > 0)
|
||||
{
|
||||
// multi GB
|
||||
long TBs = GBs / factor;
|
||||
var TBs = GBs / factor;
|
||||
if (TBs > 0)
|
||||
{
|
||||
result = TBs + ((GBs % factor) / (factor + 0.0));
|
||||
@@ -284,20 +278,18 @@ namespace ServiceLib.Common
|
||||
|
||||
public static string HumanFy(long amount)
|
||||
{
|
||||
ToHumanReadable(amount, out double result, out string unit);
|
||||
return $"{string.Format("{0:f1}", result)} {unit}";
|
||||
ToHumanReadable(amount, out var result, out var unit);
|
||||
return $"{result:f1} {unit}";
|
||||
}
|
||||
|
||||
public static string UrlEncode(string url)
|
||||
{
|
||||
return Uri.EscapeDataString(url);
|
||||
//return HttpUtility.UrlEncode(url);
|
||||
}
|
||||
|
||||
public static string UrlDecode(string url)
|
||||
{
|
||||
return Uri.UnescapeDataString(url);
|
||||
//return HttpUtility.UrlDecode(url);
|
||||
}
|
||||
|
||||
public static NameValueCollection ParseQueryString(string query)
|
||||
@@ -308,10 +300,10 @@ namespace ServiceLib.Common
|
||||
return result;
|
||||
}
|
||||
|
||||
var parts = query[1..].Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var parts = query[1..].Split('&', StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var keyValue = part.Split(['=']);
|
||||
var keyValue = part.Split('=');
|
||||
if (keyValue.Length != 2)
|
||||
{
|
||||
continue;
|
||||
@@ -328,12 +320,12 @@ namespace ServiceLib.Common
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string GetMD5(string str)
|
||||
public static string GetMd5(string str)
|
||||
{
|
||||
byte[] byteOld = Encoding.UTF8.GetBytes(str);
|
||||
byte[] byteNew = MD5.HashData(byteOld);
|
||||
var byteOld = Encoding.UTF8.GetBytes(str);
|
||||
var byteNew = MD5.HashData(byteOld);
|
||||
StringBuilder sb = new(32);
|
||||
foreach (byte b in byteNew)
|
||||
foreach (var b in byteNew)
|
||||
{
|
||||
sb.Append(b.ToString("x2"));
|
||||
}
|
||||
@@ -373,12 +365,12 @@ namespace ServiceLib.Common
|
||||
{
|
||||
if (plainText.IsNullOrEmpty()) return false;
|
||||
var buffer = new Span<byte>(new byte[plainText.Length]);
|
||||
return Convert.TryFromBase64String(plainText, buffer, out int _);
|
||||
return Convert.TryFromBase64String(plainText, buffer, out var _);
|
||||
}
|
||||
|
||||
public static string Convert2Comma(string text)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(text))
|
||||
if (IsNullOrEmpty(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
@@ -396,16 +388,7 @@ namespace ServiceLib.Common
|
||||
/// <returns></returns>
|
||||
public static bool IsNumeric(string oText)
|
||||
{
|
||||
try
|
||||
{
|
||||
int var1 = ToInt(oText);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
return oText.All(char.IsNumber);
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(string? text)
|
||||
@@ -414,11 +397,7 @@ namespace ServiceLib.Common
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (text == "null")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return text == "null";
|
||||
}
|
||||
|
||||
public static bool IsNotEmpty(string? text)
|
||||
@@ -426,41 +405,6 @@ namespace ServiceLib.Common
|
||||
return !string.IsNullOrEmpty(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IP地址是否合法
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
public static bool IsIP(string ip)
|
||||
{
|
||||
//如果为空
|
||||
if (IsNullOrEmpty(ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//清除要验证字符串中的空格
|
||||
//ip = ip.TrimEx();
|
||||
//可能是CIDR
|
||||
if (ip.IndexOf(@"/") > 0)
|
||||
{
|
||||
string[] cidr = ip.Split('/');
|
||||
if (cidr.Length == 2)
|
||||
{
|
||||
if (!IsNumeric(cidr[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ip = cidr[0];
|
||||
}
|
||||
}
|
||||
|
||||
//模式字符串
|
||||
string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
|
||||
|
||||
//验证
|
||||
return IsMatch(ip, pattern);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Domain地址是否合法
|
||||
/// </summary>
|
||||
@@ -476,19 +420,9 @@ namespace ServiceLib.Common
|
||||
return Uri.CheckHostName(domain) == UriHostNameType.Dns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证输入字符串是否与模式字符串匹配,匹配返回true
|
||||
/// </summary>
|
||||
/// <param name="input">输入字符串</param>
|
||||
/// <param name="pattern">模式字符串</param>
|
||||
public static bool IsMatch(string input, string pattern)
|
||||
{
|
||||
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
public static bool IsIpv6(string ip)
|
||||
{
|
||||
if (IPAddress.TryParse(ip, out IPAddress? address))
|
||||
if (IPAddress.TryParse(ip, out var address))
|
||||
{
|
||||
return address.AddressFamily switch
|
||||
{
|
||||
@@ -504,43 +438,20 @@ namespace ServiceLib.Common
|
||||
|
||||
#region 测速
|
||||
|
||||
public static void SetSecurityProtocol(bool enableSecurityProtocolTls13)
|
||||
private static bool PortInUse(int port)
|
||||
{
|
||||
if (enableSecurityProtocolTls13)
|
||||
{
|
||||
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
|
||||
}
|
||||
else
|
||||
{
|
||||
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
|
||||
}
|
||||
ServicePointManager.DefaultConnectionLimit = 256;
|
||||
}
|
||||
|
||||
public static bool PortInUse(int port)
|
||||
{
|
||||
bool inUse = false;
|
||||
try
|
||||
{
|
||||
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
|
||||
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
|
||||
|
||||
var lstIpEndPoints = new List<IPEndPoint>(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
||||
|
||||
foreach (IPEndPoint endPoint in ipEndPoints)
|
||||
{
|
||||
if (endPoint.Port == port)
|
||||
{
|
||||
inUse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
|
||||
var ipEndPoints = ipProperties.GetActiveTcpListeners();
|
||||
//var lstIpEndPoints = new List<IPEndPoint>(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
||||
return ipEndPoints.Any(endPoint => endPoint.Port == port);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
return inUse;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int GetFreePort(int defaultPort = 9090)
|
||||
@@ -554,7 +465,7 @@ namespace ServiceLib.Common
|
||||
|
||||
TcpListener l = new(IPAddress.Loopback, 0);
|
||||
l.Start();
|
||||
int port = ((IPEndPoint)l.LocalEndpoint).Port;
|
||||
var port = ((IPEndPoint)l.LocalEndpoint).Port;
|
||||
l.Stop();
|
||||
return port;
|
||||
}
|
||||
@@ -578,23 +489,18 @@ namespace ServiceLib.Common
|
||||
{
|
||||
if (blFull)
|
||||
{
|
||||
return string.Format("{0} - V{1} - {2}",
|
||||
Global.AppName,
|
||||
GetVersionInfo(),
|
||||
File.GetLastWriteTime(GetExePath()).ToString("yyyy/MM/dd"));
|
||||
return $"{Global.AppName} - V{GetVersionInfo()} - {File.GetLastWriteTime(GetExePath()):yyyy/MM/dd}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format("{0}/{1}",
|
||||
Global.AppName,
|
||||
GetVersionInfo());
|
||||
return $"{Global.AppName}/{GetVersionInfo()}";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
return Global.AppName;
|
||||
}
|
||||
return Global.AppName;
|
||||
}
|
||||
|
||||
public static string GetVersionInfo()
|
||||
@@ -614,7 +520,7 @@ namespace ServiceLib.Common
|
||||
/// 取得GUID
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetGUID(bool full = true)
|
||||
public static string GetGuid(bool full = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -634,14 +540,6 @@ namespace ServiceLib.Common
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static string GetDownloadFileName(string url)
|
||||
{
|
||||
var fileName = Path.GetFileName(url);
|
||||
fileName += "_temp";
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static bool IsGuidByParse(string strSrc)
|
||||
{
|
||||
return Guid.TryParse(strSrc, out _);
|
||||
@@ -667,12 +565,12 @@ namespace ServiceLib.Common
|
||||
public static Dictionary<string, string> GetSystemHosts()
|
||||
{
|
||||
var systemHosts = new Dictionary<string, string>();
|
||||
var hostfile = @"C:\Windows\System32\drivers\etc\hosts";
|
||||
var hostFile = @"C:\Windows\System32\drivers\etc\hosts";
|
||||
try
|
||||
{
|
||||
if (File.Exists(hostfile))
|
||||
if (File.Exists(hostFile))
|
||||
{
|
||||
var hosts = File.ReadAllText(hostfile).Replace("\r", "");
|
||||
var hosts = File.ReadAllText(hostFile).Replace("\r", "");
|
||||
var hostsList = hosts.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (var host in hostsList)
|
||||
@@ -693,10 +591,10 @@ namespace ServiceLib.Common
|
||||
|
||||
public static async Task<string?> GetCliWrapOutput(string filePath, string? arg)
|
||||
{
|
||||
return await GetCliWrapOutput(filePath, arg != null ? [arg] : null);
|
||||
return await GetCliWrapOutput(filePath, arg != null ? new List<string>() { arg } : null);
|
||||
}
|
||||
|
||||
public static async Task<string?> GetCliWrapOutput(string filePath, IEnumerable<string>? args)
|
||||
private static async Task<string?> GetCliWrapOutput(string filePath, IEnumerable<string>? args)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -736,7 +634,7 @@ namespace ServiceLib.Common
|
||||
/// <returns></returns>
|
||||
public static string GetPath(string fileName)
|
||||
{
|
||||
string startupPath = StartupPath();
|
||||
var startupPath = StartupPath();
|
||||
if (IsNullOrEmpty(fileName))
|
||||
{
|
||||
return startupPath;
|
||||
@@ -760,113 +658,104 @@ namespace ServiceLib.Common
|
||||
|
||||
public static string GetTempPath(string filename = "")
|
||||
{
|
||||
string _tempPath = Path.Combine(StartupPath(), "guiTemps");
|
||||
if (!Directory.Exists(_tempPath))
|
||||
var tempPath = Path.Combine(StartupPath(), "guiTemps");
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(filename))
|
||||
if (IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
return tempPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(_tempPath, filename);
|
||||
return Path.Combine(tempPath, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static string UnGzip(byte[] buf)
|
||||
{
|
||||
using MemoryStream sb = new();
|
||||
using GZipStream input = new(new MemoryStream(buf), CompressionMode.Decompress, false);
|
||||
input.CopyTo(sb);
|
||||
sb.Position = 0;
|
||||
return new StreamReader(sb, Encoding.UTF8).ReadToEnd();
|
||||
}
|
||||
|
||||
public static string GetBackupPath(string filename)
|
||||
{
|
||||
string _tempPath = Path.Combine(StartupPath(), "guiBackups");
|
||||
if (!Directory.Exists(_tempPath))
|
||||
var tempPath = Path.Combine(StartupPath(), "guiBackups");
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
return Path.Combine(_tempPath, filename);
|
||||
return Path.Combine(tempPath, filename);
|
||||
}
|
||||
|
||||
public static string GetConfigPath(string filename = "")
|
||||
{
|
||||
string _tempPath = Path.Combine(StartupPath(), "guiConfigs");
|
||||
if (!Directory.Exists(_tempPath))
|
||||
var tempPath = Path.Combine(StartupPath(), "guiConfigs");
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
return tempPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(_tempPath, filename);
|
||||
return Path.Combine(tempPath, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetBinPath(string filename, string? coreType = null)
|
||||
{
|
||||
string _tempPath = Path.Combine(StartupPath(), "bin");
|
||||
if (!Directory.Exists(_tempPath))
|
||||
var tempPath = Path.Combine(StartupPath(), "bin");
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
if (coreType != null)
|
||||
{
|
||||
_tempPath = Path.Combine(_tempPath, coreType.ToString());
|
||||
if (!Directory.Exists(_tempPath))
|
||||
tempPath = Path.Combine(tempPath, coreType.ToString());
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(filename))
|
||||
if (IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
return tempPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(_tempPath, filename);
|
||||
return Path.Combine(tempPath, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetLogPath(string filename = "")
|
||||
{
|
||||
string _tempPath = Path.Combine(StartupPath(), "guiLogs");
|
||||
if (!Directory.Exists(_tempPath))
|
||||
var tempPath = Path.Combine(StartupPath(), "guiLogs");
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
return tempPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(_tempPath, filename);
|
||||
return Path.Combine(tempPath, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFontsPath(string filename = "")
|
||||
{
|
||||
string _tempPath = Path.Combine(StartupPath(), "guiFonts");
|
||||
if (!Directory.Exists(_tempPath))
|
||||
var tempPath = Path.Combine(StartupPath(), "guiFonts");
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
return tempPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(_tempPath, filename);
|
||||
return Path.Combine(tempPath, filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -882,14 +771,7 @@ namespace ServiceLib.Common
|
||||
|
||||
public static string GetExeName(string name)
|
||||
{
|
||||
if (IsWindows())
|
||||
{
|
||||
return $"{name}.exe";
|
||||
}
|
||||
else
|
||||
{
|
||||
return name;
|
||||
}
|
||||
return IsWindows() ? $"{name}.exe" : name;
|
||||
}
|
||||
|
||||
public static bool IsAdministrator()
|
||||
@@ -901,7 +783,7 @@ namespace ServiceLib.Common
|
||||
else
|
||||
{
|
||||
var id = GetLinuxUserId().Result ?? "1000";
|
||||
if (int.TryParse(id, out int userId))
|
||||
if (int.TryParse(id, out var userId))
|
||||
{
|
||||
return userId == 0;
|
||||
}
|
||||
@@ -914,7 +796,8 @@ namespace ServiceLib.Common
|
||||
|
||||
private static async Task<string?> GetLinuxUserId()
|
||||
{
|
||||
return await GetCliWrapOutput("/bin/bash", ["-c", "id -u"]);
|
||||
var arg = new List<string>() { "-c", "id -u" };
|
||||
return await GetCliWrapOutput("/bin/bash", arg);
|
||||
}
|
||||
|
||||
#endregion Platform
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ServiceLib.Common
|
||||
.Build();
|
||||
try
|
||||
{
|
||||
T obj = deserializer.Deserialize<T>(str);
|
||||
var obj = deserializer.Deserialize<T>(str);
|
||||
return obj;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -36,9 +36,9 @@ namespace ServiceLib.Common
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToYaml(Object? obj)
|
||||
public static string ToYaml(object? obj)
|
||||
{
|
||||
string result = string.Empty;
|
||||
var result = string.Empty;
|
||||
if (obj == null)
|
||||
{
|
||||
return result;
|
||||
|
||||
@@ -114,6 +114,11 @@
|
||||
@"http://www.msftconnecttest.com/connecttest.txt",
|
||||
};
|
||||
|
||||
public static readonly List<string> GeoFilesSources = new() {
|
||||
GeoUrl,
|
||||
@"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/{0}.dat",
|
||||
};
|
||||
|
||||
public static readonly Dictionary<string, string> UserAgentTexts = new()
|
||||
{
|
||||
{"chrome","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36" },
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
{
|
||||
public sealed class AppHandler
|
||||
{
|
||||
#region Property
|
||||
|
||||
private static readonly Lazy<AppHandler> _instance = new(() => new());
|
||||
private Config _config;
|
||||
private int? _statePort;
|
||||
private int? _statePort2;
|
||||
private Job? _processJob;
|
||||
private bool? _isAdministrator;
|
||||
public static AppHandler Instance => _instance.Value;
|
||||
public Config Config => _config;
|
||||
|
||||
@@ -28,6 +31,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAdministrator
|
||||
{
|
||||
get
|
||||
{
|
||||
_isAdministrator ??= Utils.IsAdministrator();
|
||||
return _isAdministrator.Value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Property
|
||||
|
||||
#region Init
|
||||
|
||||
public AppHandler()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Data;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
|
||||
namespace ServiceLib.Handler
|
||||
{
|
||||
@@ -494,7 +493,7 @@ namespace ServiceLib.Handler
|
||||
return -1;
|
||||
}
|
||||
var ext = Path.GetExtension(fileName);
|
||||
string newFileName = $"{Utils.GetGUID()}{ext}";
|
||||
string newFileName = $"{Utils.GetGuid()}{ext}";
|
||||
//newFileName = Path.Combine(Utile.GetTempPath(), newFileName);
|
||||
|
||||
try
|
||||
@@ -934,7 +933,7 @@ namespace ServiceLib.Handler
|
||||
var maxSort = -1;
|
||||
if (Utils.IsNullOrEmpty(profileItem.indexId))
|
||||
{
|
||||
profileItem.indexId = Utils.GetGUID(false);
|
||||
profileItem.indexId = Utils.GetGuid(false);
|
||||
maxSort = ProfileExHandler.Instance.GetMaxSort();
|
||||
}
|
||||
if (!toFile && maxSort < 0)
|
||||
@@ -1002,7 +1001,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static int AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType, out string indexId)
|
||||
{
|
||||
indexId = Utils.GetMD5(Global.CoreMultipleLoadConfigFileName);
|
||||
indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
|
||||
string configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName);
|
||||
if (CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType, out string msg) != 0)
|
||||
{
|
||||
@@ -1341,7 +1340,7 @@ namespace ServiceLib.Handler
|
||||
try
|
||||
{
|
||||
var uri = new Uri(url);
|
||||
var queryVars = HttpUtility.ParseQueryString(uri.Query);
|
||||
var queryVars = Utils.ParseQueryString(uri.Query);
|
||||
subItem.remarks = queryVars["remarks"] ?? "import_sub";
|
||||
}
|
||||
catch (UriFormatException)
|
||||
@@ -1378,7 +1377,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
if (Utils.IsNullOrEmpty(item.id))
|
||||
{
|
||||
item.id = Utils.GetGUID(false);
|
||||
item.id = Utils.GetGuid(false);
|
||||
|
||||
if (item.sort <= 0)
|
||||
{
|
||||
@@ -1461,7 +1460,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(item.id))
|
||||
{
|
||||
item.id = Utils.GetGUID(false);
|
||||
item.id = Utils.GetGuid(false);
|
||||
}
|
||||
|
||||
if (SQLiteHelper.Instance.Replace(item) > 0)
|
||||
@@ -1495,14 +1494,14 @@ namespace ServiceLib.Handler
|
||||
|
||||
foreach (var item in lstRules)
|
||||
{
|
||||
item.id = Utils.GetGUID(false);
|
||||
item.id = Utils.GetGuid(false);
|
||||
}
|
||||
routingItem.ruleNum = lstRules.Count;
|
||||
routingItem.ruleSet = JsonUtils.Serialize(lstRules, false);
|
||||
|
||||
if (Utils.IsNullOrEmpty(routingItem.id))
|
||||
{
|
||||
routingItem.id = Utils.GetGUID(false);
|
||||
routingItem.id = Utils.GetGuid(false);
|
||||
}
|
||||
|
||||
if (SQLiteHelper.Instance.Replace(routingItem) > 0)
|
||||
@@ -1711,7 +1710,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(item.id))
|
||||
{
|
||||
item.id = Utils.GetGUID(false);
|
||||
item.id = Utils.GetGuid(false);
|
||||
}
|
||||
|
||||
if (SQLiteHelper.Instance.Replace(item) > 0)
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace ServiceLib.Handler.Fmt
|
||||
|
||||
protected static string WriteAllText(string strData, string ext = "json")
|
||||
{
|
||||
var fileName = Utils.GetTempPath($"{Utils.GetGUID(false)}.{ext}");
|
||||
var fileName = Utils.GetTempPath($"{Utils.GetGuid(false)}.{ext}");
|
||||
File.WriteAllText(fileName, strData);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
item.network = Global.DefaultNetwork;
|
||||
item.headerType = Global.None;
|
||||
|
||||
item.configVersion = Utils.ToInt(vmessQRCode.v);
|
||||
item.configVersion = vmessQRCode.v;
|
||||
item.remarks = Utils.ToString(vmessQRCode.ps);
|
||||
item.address = Utils.ToString(vmessQRCode.add);
|
||||
item.port = Utils.ToInt(vmessQRCode.port);
|
||||
item.port = vmessQRCode.port;
|
||||
item.id = Utils.ToString(vmessQRCode.id);
|
||||
item.alterId = Utils.ToInt(vmessQRCode.aid);
|
||||
item.alterId = vmessQRCode.aid;
|
||||
item.security = Utils.ToString(vmessQRCode.scy);
|
||||
|
||||
item.security = Utils.IsNotEmpty(vmessQRCode.scy) ? vmessQRCode.scy : Global.DefaultSecurity;
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
{
|
||||
public string defIEProxyExceptions { get; set; }
|
||||
public string subConvertUrl { get; set; } = string.Empty;
|
||||
public string? geoSourceUrl { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace ServiceLib.Models
|
||||
return summary;
|
||||
}
|
||||
|
||||
public List<string> GetAlpn()
|
||||
public List<string>? GetAlpn()
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(alpn))
|
||||
{
|
||||
|
||||
@@ -120,10 +120,10 @@
|
||||
public string? version { get; set; }
|
||||
public string? network { get; set; }
|
||||
public string? packet_encoding { get; set; }
|
||||
public string[]? local_address { get; set; }
|
||||
public List<string>? local_address { get; set; }
|
||||
public string? private_key { get; set; }
|
||||
public string? peer_public_key { get; set; }
|
||||
public int[]? reserved { get; set; }
|
||||
public List<int>? reserved { get; set; }
|
||||
public int? mtu { get; set; }
|
||||
public string? plugin { get; set; }
|
||||
public string? plugin_opts { get; set; }
|
||||
@@ -138,11 +138,11 @@
|
||||
public class Tls4Sbox
|
||||
{
|
||||
public bool enabled { get; set; }
|
||||
public string server_name { get; set; }
|
||||
public string? server_name { get; set; }
|
||||
public bool? insecure { get; set; }
|
||||
public List<string> alpn { get; set; }
|
||||
public Utls4Sbox utls { get; set; }
|
||||
public Reality4Sbox reality { get; set; }
|
||||
public List<string>? alpn { get; set; }
|
||||
public Utls4Sbox? utls { get; set; }
|
||||
public Reality4Sbox? reality { get; set; }
|
||||
}
|
||||
|
||||
public class Multiplex4Sbox
|
||||
|
||||
@@ -647,12 +647,12 @@ namespace ServiceLib.Models
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string path { get; set; }
|
||||
public string? path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<string> host { get; set; }
|
||||
public List<string>? host { get; set; }
|
||||
}
|
||||
|
||||
public class QuicSettings4Ray
|
||||
|
||||
+9
@@ -3004,6 +3004,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Geo files source (optional) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsGeoFilesSource {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsGeoFilesSource", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 HTTP Port 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1322,9 +1322,12 @@
|
||||
<value>Host filter</value>
|
||||
</data>
|
||||
<data name="TipActiveServer" xml:space="preserve">
|
||||
<value>Active</value>
|
||||
<value>Active</value>
|
||||
</data>
|
||||
<data name="menuStorageUI" xml:space="preserve">
|
||||
<value>Save Interface Layout</value>
|
||||
</data>
|
||||
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
||||
<value>Geo files source (optional)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1324,4 +1324,7 @@
|
||||
<data name="menuStorageUI" xml:space="preserve">
|
||||
<value>保存界面布局</value>
|
||||
</data>
|
||||
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
||||
<value>Geo文件来源(可选)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1204,4 +1204,7 @@
|
||||
<data name="menuStorageUI" xml:space="preserve">
|
||||
<value>儲存介面佈局</value>
|
||||
</data>
|
||||
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
||||
<value>Geo文件來源(可選)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -3,13 +3,13 @@
|
||||
{
|
||||
"tag": "remote",
|
||||
"address": "8.8.8.8",
|
||||
"strategy": "ipv4_only",
|
||||
"strategy": "prefer_ipv4",
|
||||
"detour": "proxy"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"address": "223.5.5.5",
|
||||
"strategy": "ipv4_only",
|
||||
"strategy": "prefer_ipv4",
|
||||
"detour": "direct"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
{
|
||||
"tag": "remote",
|
||||
"address": "8.8.8.8",
|
||||
"strategy": "ipv4_only",
|
||||
"strategy": "prefer_ipv4",
|
||||
"detour": "proxy"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"address": "223.5.5.5",
|
||||
"strategy": "ipv4_only",
|
||||
"strategy": "prefer_ipv4",
|
||||
"detour": "direct"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -678,8 +678,8 @@ namespace ServiceLib.Services.CoreConfig
|
||||
{
|
||||
outbound.private_key = node.id;
|
||||
outbound.peer_public_key = node.publicKey;
|
||||
outbound.reserved = Utils.String2List(node.path).Select(int.Parse).ToArray();
|
||||
outbound.local_address = [.. Utils.String2List(node.requestHost)];
|
||||
outbound.reserved = Utils.String2List(node.path)?.Select(int.Parse).ToList();
|
||||
outbound.local_address = Utils.String2List(node.requestHost);
|
||||
outbound.mtu = Utils.ToInt(node.shortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.shortId);
|
||||
break;
|
||||
}
|
||||
@@ -732,7 +732,7 @@ namespace ServiceLib.Services.CoreConfig
|
||||
}
|
||||
else if (Utils.IsNotEmpty(node.requestHost))
|
||||
{
|
||||
server_name = Utils.String2List(node.requestHost)[0];
|
||||
server_name = Utils.String2List(node.requestHost)?.First();
|
||||
}
|
||||
var tls = new Tls4Sbox()
|
||||
{
|
||||
|
||||
@@ -829,7 +829,7 @@ namespace ServiceLib.Services.CoreConfig
|
||||
}
|
||||
else if (Utils.IsNotEmpty(host))
|
||||
{
|
||||
tlsSettings.serverName = Utils.String2List(host)[0];
|
||||
tlsSettings.serverName = Utils.String2List(host)?.First();
|
||||
}
|
||||
streamSettings.tlsSettings = tlsSettings;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ServiceLib.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
|
||||
var progress = new Progress<string>();
|
||||
progress.ProgressChanged += (sender, value) =>
|
||||
@@ -62,7 +62,7 @@ namespace ServiceLib.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, $"{ResUI.Downloading} {url}"));
|
||||
|
||||
var progress = new Progress<double>();
|
||||
@@ -92,7 +92,7 @@ namespace ServiceLib.Services
|
||||
|
||||
public async Task<string?> UrlRedirectAsync(string url, bool blProxy)
|
||||
{
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
var webRequestHandler = new SocketsHttpHandler
|
||||
{
|
||||
AllowAutoRedirect = false,
|
||||
@@ -181,7 +181,7 @@ namespace ServiceLib.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
var webProxy = GetWebProxy(blProxy);
|
||||
var client = new HttpClient(new SocketsHttpHandler()
|
||||
{
|
||||
@@ -226,7 +226,7 @@ namespace ServiceLib.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
|
||||
var webProxy = GetWebProxy(blProxy);
|
||||
|
||||
@@ -337,5 +337,18 @@ namespace ServiceLib.Services
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetSecurityProtocol(bool enableSecurityProtocolTls13)
|
||||
{
|
||||
if (enableSecurityProtocolTls13)
|
||||
{
|
||||
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
|
||||
}
|
||||
else
|
||||
{
|
||||
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
|
||||
}
|
||||
ServicePointManager.DefaultConnectionLimit = 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace ServiceLib.Services
|
||||
_updateFunc?.Invoke(false, args.Msg);
|
||||
|
||||
url = args.Url;
|
||||
fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
fileName = Utils.GetTempPath(Utils.GetGuid());
|
||||
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||
}
|
||||
else
|
||||
@@ -108,7 +108,7 @@ namespace ServiceLib.Services
|
||||
|
||||
url = args.Url;
|
||||
var ext = Path.GetExtension(url);
|
||||
fileName = Utils.GetTempPath(Utils.GetGUID() + ext);
|
||||
fileName = Utils.GetTempPath(Utils.GetGuid() + ext);
|
||||
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||
}
|
||||
else
|
||||
@@ -255,8 +255,8 @@ namespace ServiceLib.Services
|
||||
|
||||
public async Task UpdateGeoFileAll(Config config, Action<bool, string> updateFunc)
|
||||
{
|
||||
await UpdateGeoFile("geosite", _config, updateFunc);
|
||||
await UpdateGeoFile("geoip", _config, updateFunc);
|
||||
await UpdateGeoFile("geosite", config, updateFunc);
|
||||
await UpdateGeoFile("geoip", config, updateFunc);
|
||||
_updateFunc?.Invoke(true, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, "geo"));
|
||||
}
|
||||
|
||||
@@ -450,8 +450,12 @@ namespace ServiceLib.Services
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = updateFunc;
|
||||
|
||||
var geoUrl = string.IsNullOrEmpty(config?.constItem.geoSourceUrl)
|
||||
? Global.GeoUrl
|
||||
: config.constItem.geoSourceUrl;
|
||||
var url = string.Format(Global.GeoUrl, geoName);
|
||||
var fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
var fileName = Utils.GetTempPath(Utils.GetGuid());
|
||||
|
||||
DownloadService downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace ServiceLib.ViewModels
|
||||
private async Task RemoteRestore()
|
||||
{
|
||||
DisplayOperationMsg();
|
||||
var fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
var fileName = Utils.GetTempPath(Utils.GetGuid());
|
||||
var result = await WebDavHandler.Instance.GetRawFile(fileName);
|
||||
if (result)
|
||||
{
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace ServiceLib.ViewModels
|
||||
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
|
||||
if (ret == true)
|
||||
{
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStaus();
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStatus();
|
||||
Reload();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace ServiceLib.ViewModels
|
||||
[Reactive] public bool EnableHWA { get; set; }
|
||||
[Reactive] public string SubConvertUrl { get; set; }
|
||||
[Reactive] public int MainGirdOrientation { get; set; }
|
||||
[Reactive] public string GeoFileSourceUrl { get; set; }
|
||||
|
||||
#endregion UI
|
||||
|
||||
@@ -164,6 +165,7 @@ namespace ServiceLib.ViewModels
|
||||
EnableHWA = _config.guiItem.enableHWA;
|
||||
SubConvertUrl = _config.constItem.subConvertUrl;
|
||||
MainGirdOrientation = (int)_config.uiItem.mainGirdOrientation;
|
||||
GeoFileSourceUrl = _config.constItem.geoSourceUrl;
|
||||
|
||||
#endregion UI
|
||||
|
||||
@@ -316,6 +318,7 @@ namespace ServiceLib.ViewModels
|
||||
_config.guiItem.enableHWA = EnableHWA;
|
||||
_config.constItem.subConvertUrl = SubConvertUrl;
|
||||
_config.uiItem.mainGirdOrientation = (EGirdOrientation)MainGirdOrientation;
|
||||
_config.constItem.geoSourceUrl = GeoFileSourceUrl;
|
||||
|
||||
//systemProxy
|
||||
_config.systemProxyItem.systemProxyExceptions = systemProxyExceptions;
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
if (rulesItem.id.IsNullOrEmpty())
|
||||
{
|
||||
rulesItem.id = Utils.GetGUID(false);
|
||||
rulesItem.id = Utils.GetGuid(false);
|
||||
rulesItem.outboundTag = Global.ProxyTag;
|
||||
rulesItem.enabled = true;
|
||||
SelectedSource = rulesItem;
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace ServiceLib.ViewModels
|
||||
var item = SelectedRouting;
|
||||
foreach (var it in _rules)
|
||||
{
|
||||
it.id = Utils.GetGUID(false);
|
||||
it.id = Utils.GetGuid(false);
|
||||
}
|
||||
item.ruleNum = _rules.Count;
|
||||
item.ruleSet = JsonUtils.Serialize(_rules, false);
|
||||
@@ -322,7 +322,7 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
foreach (var rule in lstRules)
|
||||
{
|
||||
rule.id = Utils.GetGUID(false);
|
||||
rule.id = Utils.GetGuid(false);
|
||||
}
|
||||
|
||||
if (blReplace)
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
public class StatusBarViewModel : MyReactiveObject
|
||||
{
|
||||
private bool _isAdministrator { get; set; }
|
||||
|
||||
#region ObservableCollection
|
||||
|
||||
private IObservableCollection<RoutingItem> _routingItems = new ObservableCollectionExtended<RoutingItem>();
|
||||
@@ -108,19 +106,16 @@ namespace ServiceLib.ViewModels
|
||||
public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
|
||||
if (_updateView != null)
|
||||
if (updateView != null)
|
||||
{
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString())
|
||||
.Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
Init(updateView);
|
||||
}
|
||||
|
||||
SelectedRouting = new();
|
||||
SelectedServer = new();
|
||||
|
||||
_isAdministrator = Utils.IsAdministrator();
|
||||
if (_config.tunModeItem.enableTun && _isAdministrator)
|
||||
if (_config.tunModeItem.enableTun && AppHandler.Instance.IsAdministrator)
|
||||
{
|
||||
EnableTun = true;
|
||||
}
|
||||
@@ -130,7 +125,7 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
|
||||
RefreshRoutingsMenu();
|
||||
InboundDisplayStaus();
|
||||
InboundDisplayStatus();
|
||||
ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, true);
|
||||
|
||||
#region WhenAnyValue && ReactiveCommand
|
||||
@@ -414,7 +409,7 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
_config.tunModeItem.enableTun = EnableTun;
|
||||
// When running as a non-administrator, reboot to administrator mode
|
||||
if (EnableTun && !_isAdministrator)
|
||||
if (EnableTun && !AppHandler.Instance.IsAdministrator)
|
||||
{
|
||||
_config.tunModeItem.enableTun = false;
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||
@@ -429,19 +424,12 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
#region UI
|
||||
|
||||
public void InboundDisplayStaus()
|
||||
public void InboundDisplayStatus()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]");
|
||||
sb.Append(" | ");
|
||||
//if (_config.systemProxyItem.sysProxyType == ESysProxyType.ForcedChange)
|
||||
//{
|
||||
// sb.Append($"[{Global.InboundHttp}({ResUI.SystemProxy}):{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
sb.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http)}]");
|
||||
//}
|
||||
InboundDisplay = $"{ResUI.LabLocal}:{sb}";
|
||||
|
||||
if (_config.inbound[0].allowLANConn)
|
||||
|
||||
@@ -43,7 +43,7 @@ public partial class App : Application
|
||||
|
||||
private void OnStartup(string[]? Args)
|
||||
{
|
||||
var exePathKey = Utils.GetMD5(Utils.GetExePath());
|
||||
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
||||
|
||||
var rebootas = (Args ?? new string[] { }).Any(t => t == Global.RebootAs);
|
||||
//ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
||||
|
||||
@@ -272,7 +272,7 @@ namespace v2rayN.Desktop.Views
|
||||
private void btnGUID_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
txtId.Text =
|
||||
txtId5.Text = Utils.GetGUID();
|
||||
txtId5.Text = Utils.GetGuid();
|
||||
}
|
||||
|
||||
private void SetHeaderType()
|
||||
|
||||
@@ -80,30 +80,35 @@ namespace v2rayN.Desktop.Views
|
||||
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
||||
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
switch (_config.uiItem.mainGirdOrientation)
|
||||
{
|
||||
gridMain.IsVisible = true;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections.IsVisible).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain.SelectedIndex).DisposeWith(disposables);
|
||||
}
|
||||
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
|
||||
{
|
||||
gridMain1.IsVisible = true;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies1.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections1.IsVisible).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain1.SelectedIndex).DisposeWith(disposables);
|
||||
}
|
||||
else
|
||||
{
|
||||
gridMain2.IsVisible = true;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies2.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections2.IsVisible).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
|
||||
case EGirdOrientation.Horizontal:
|
||||
gridMain.IsVisible = true;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabMsgView.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections.IsVisible).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain.SelectedIndex).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Vertical:
|
||||
gridMain1.IsVisible = true;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabMsgView1.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies1.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections1.IsVisible).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain1.SelectedIndex).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Tab:
|
||||
default:
|
||||
gridMain2.IsVisible = true;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies2.IsVisible).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections2.IsVisible).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
menuGlobalHotkeySetting.IsVisible = false;
|
||||
@@ -115,26 +120,29 @@ namespace v2rayN.Desktop.Views
|
||||
menuGlobalHotkeySetting.IsVisible = false;
|
||||
}
|
||||
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
switch (_config.uiItem.mainGirdOrientation)
|
||||
{
|
||||
tabProfiles.Content ??= new ProfilesView(this);
|
||||
tabMsgView.Content ??= new MsgView();
|
||||
tabClashProxies.Content ??= new ClashProxiesView();
|
||||
tabClashConnections.Content ??= new ClashConnectionsView();
|
||||
}
|
||||
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
|
||||
{
|
||||
tabProfiles1.Content ??= new ProfilesView(this);
|
||||
tabMsgView1.Content ??= new MsgView();
|
||||
tabClashProxies1.Content ??= new ClashProxiesView();
|
||||
tabClashConnections1.Content ??= new ClashConnectionsView();
|
||||
}
|
||||
else
|
||||
{
|
||||
tabProfiles2.Content ??= new ProfilesView(this);
|
||||
tabMsgView2.Content ??= new MsgView();
|
||||
tabClashProxies2.Content ??= new ClashProxiesView();
|
||||
tabClashConnections2.Content ??= new ClashConnectionsView();
|
||||
case EGirdOrientation.Horizontal:
|
||||
tabProfiles.Content ??= new ProfilesView(this);
|
||||
tabMsgView.Content ??= new MsgView();
|
||||
tabClashProxies.Content ??= new ClashProxiesView();
|
||||
tabClashConnections.Content ??= new ClashConnectionsView();
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Vertical:
|
||||
tabProfiles1.Content ??= new ProfilesView(this);
|
||||
tabMsgView1.Content ??= new MsgView();
|
||||
tabClashProxies1.Content ??= new ClashProxiesView();
|
||||
tabClashConnections1.Content ??= new ClashConnectionsView();
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Tab:
|
||||
default:
|
||||
tabProfiles2.Content ??= new ProfilesView(this);
|
||||
tabMsgView2.Content ??= new MsgView();
|
||||
tabClashProxies2.Content ??= new ClashProxiesView();
|
||||
tabClashConnections2.Content ??= new ClashConnectionsView();
|
||||
break;
|
||||
}
|
||||
conTheme.Content ??= new ThemeSettingView();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
Cursor="Hand" />
|
||||
</StackPanel>
|
||||
|
||||
<TabControl HorizontalContentAlignment="Left">
|
||||
<TabControl HorizontalContentAlignment="Stretch">
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCore}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||
<Grid Classes="Margin8">
|
||||
@@ -364,6 +364,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -610,6 +611,19 @@
|
||||
Grid.Column="1"
|
||||
Width="300"
|
||||
Classes="Margin8" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="22"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Classes="Margin8"
|
||||
Text="{x:Static resx:ResUI.TbSettingsGeoFilesSource}" />
|
||||
<ComboBox
|
||||
x:Name="cmbGetFilesSourceUrl"
|
||||
Grid.Row="22"
|
||||
Grid.Column="1"
|
||||
Width="300"
|
||||
Classes="Margin8" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
@@ -83,6 +83,10 @@ namespace v2rayN.Desktop.Views
|
||||
{
|
||||
cmbSubConvertUrl.Items.Add(it);
|
||||
});
|
||||
Global.GeoFilesSources.ForEach(it =>
|
||||
{
|
||||
cmbGetFilesSourceUrl.Items.Add(it);
|
||||
});
|
||||
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
|
||||
{
|
||||
cmbMainGirdOrientation.Items.Add(it.ToString());
|
||||
@@ -132,6 +136,7 @@ namespace v2rayN.Desktop.Views
|
||||
this.Bind(ViewModel, vm => vm.SpeedPingTestUrl, v => v.cmbSpeedPingTestUrl.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.MainGirdOrientation, v => v.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.GeoFileSourceUrl, v => v.cmbGetFilesSourceUrl.SelectedValue).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.notProxyLocalAddress, v => v.tognotProxyLocalAddress.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.SelectedValue).DisposeWith(disposables);
|
||||
|
||||
@@ -24,23 +24,47 @@
|
||||
|
||||
<conv:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
<Thickness
|
||||
x:Key="ServerItemMargin"
|
||||
x:Key="Margin4"
|
||||
Bottom="4"
|
||||
Left="4"
|
||||
Right="4"
|
||||
Top="4" />
|
||||
<Thickness
|
||||
x:Key="SettingItemMargin"
|
||||
x:Key="Margin8"
|
||||
Bottom="8"
|
||||
Left="8"
|
||||
Right="8"
|
||||
Top="8" />
|
||||
<Thickness
|
||||
x:Key="OutlinedTextBoxDefaultPadding"
|
||||
Bottom="12"
|
||||
Left="16"
|
||||
Right="12"
|
||||
Top="12" />
|
||||
Bottom="8"
|
||||
Left="8"
|
||||
Right="8"
|
||||
Top="8" />
|
||||
<Thickness
|
||||
x:Key="MarginLeftRight4"
|
||||
Bottom="0"
|
||||
Left="4"
|
||||
Right="4"
|
||||
Top="0" />
|
||||
<Thickness
|
||||
x:Key="MarginLeftRight8"
|
||||
Bottom="0"
|
||||
Left="8"
|
||||
Right="8"
|
||||
Top="0" />
|
||||
<Thickness
|
||||
x:Key="MarginLeft8"
|
||||
Bottom="0"
|
||||
Left="8"
|
||||
Right="0"
|
||||
Top="0" />
|
||||
<Thickness
|
||||
x:Key="MarginRight8"
|
||||
Bottom="0"
|
||||
Left="0"
|
||||
Right="8"
|
||||
Top="0" />
|
||||
<Style
|
||||
x:Key="ModuleTitle"
|
||||
BasedOn="{StaticResource MaterialDesignTextBlock}"
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace v2rayN
|
||||
/// <param name="e"></param>
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
var exePathKey = Utils.GetMD5(Utils.GetExePath());
|
||||
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
||||
|
||||
var rebootas = (e.Args ?? new string[] { }).Any(t => t == Global.RebootAs);
|
||||
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace v2rayN
|
||||
{
|
||||
try
|
||||
{
|
||||
var autoRunName = $"{AutoRunName}_{Utils.GetMD5(Utils.StartupPath())}";
|
||||
var autoRunName = $"{AutoRunName}_{Utils.GetMd5(Utils.StartupPath())}";
|
||||
//delete first
|
||||
RegWriteValue(AutoRunRegPath, autoRunName, "");
|
||||
if (Utils.IsAdministrator())
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="8">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Center"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
@@ -37,7 +37,7 @@
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbCancel}"
|
||||
Cursor="Hand"
|
||||
IsCancel="true"
|
||||
@@ -72,14 +72,14 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource ModuleTitle}"
|
||||
Text="{x:Static resx:ResUI.menuServers}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbRemarks}" />
|
||||
@@ -89,7 +89,7 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource MyOutlinedTextBox}" />
|
||||
@@ -97,7 +97,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAddress}" />
|
||||
@@ -106,7 +106,7 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
IsReadOnly="True"
|
||||
@@ -118,12 +118,12 @@
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
x:Name="btnBrowse"
|
||||
Margin="2,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
<Button
|
||||
x:Name="btnEdit"
|
||||
Margin="2,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Content="{x:Static resx:ResUI.TbEdit}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
@@ -131,7 +131,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbCoreType}" />
|
||||
@@ -140,7 +140,7 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
MaxDropDownHeight="1000"
|
||||
Style="{StaticResource MyOutlinedTextComboBox}" />
|
||||
@@ -148,18 +148,18 @@
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbDisplayLog}" />
|
||||
<StackPanel
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Orientation="Horizontal">
|
||||
<ToggleButton x:Name="togDisplayLog" HorizontalAlignment="Left" />
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TipDisplayLog}" />
|
||||
@@ -168,7 +168,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPreSocksPort}" />
|
||||
@@ -177,7 +177,7 @@
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource MyOutlinedTextBox}" />
|
||||
@@ -193,7 +193,7 @@
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
Width="500"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.CustomServerTips}"
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="8">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Center"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
@@ -37,7 +37,7 @@
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbCancel}"
|
||||
Cursor="Hand"
|
||||
IsCancel="true"
|
||||
@@ -76,7 +76,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource ModuleTitle}"
|
||||
Text="{x:Static resx:ResUI.menuServers}" />
|
||||
<StackPanel
|
||||
@@ -86,7 +86,7 @@
|
||||
<ComboBox
|
||||
x:Name="cmbCoreType"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbCoreType}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
@@ -94,7 +94,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbRemarks}" />
|
||||
@@ -103,13 +103,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAddress}" />
|
||||
@@ -118,13 +118,13 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPort}" />
|
||||
@@ -133,7 +133,7 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
@@ -162,7 +162,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId}" />
|
||||
@@ -171,20 +171,20 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<Button
|
||||
x:Name="btnGUID"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="4,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Content="{x:Static resx:ResUI.TbGUID}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAlterId}" />
|
||||
@@ -193,14 +193,14 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSecurity}" />
|
||||
@@ -209,7 +209,7 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -230,7 +230,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
@@ -239,13 +239,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSecurity3}" />
|
||||
@@ -254,7 +254,7 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="300"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -275,7 +275,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSecurity4}" />
|
||||
@@ -284,13 +284,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId4}" />
|
||||
@@ -299,7 +299,7 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -321,7 +321,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId5}" />
|
||||
@@ -330,20 +330,20 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<Button
|
||||
x:Name="btnGUID5"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="4,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Content="{x:Static resx:ResUI.TbGUID}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbFlow5}" />
|
||||
@@ -352,13 +352,13 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSecurity5}" />
|
||||
@@ -367,7 +367,7 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
@@ -389,7 +389,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
@@ -398,13 +398,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbFlow5}" />
|
||||
@@ -413,7 +413,7 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -434,7 +434,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
@@ -443,13 +443,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPath7}" />
|
||||
@@ -458,7 +458,7 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -479,7 +479,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId}" />
|
||||
@@ -488,13 +488,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
@@ -503,13 +503,13 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||
@@ -518,7 +518,7 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -541,7 +541,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPrivateKey}" />
|
||||
@@ -550,13 +550,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPublicKey}" />
|
||||
@@ -565,14 +565,14 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbReserved}" />
|
||||
@@ -581,13 +581,13 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbLocalAddress}" />
|
||||
@@ -596,13 +596,13 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="Mtu" />
|
||||
@@ -611,7 +611,7 @@
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
@@ -642,14 +642,14 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource ModuleTitle}"
|
||||
Text="{x:Static resx:ResUI.GbTransport}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbNetwork}" />
|
||||
@@ -658,12 +658,12 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TipNetwork}" />
|
||||
@@ -672,7 +672,7 @@
|
||||
x:Name="labHeaderType"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbHeaderType}" />
|
||||
@@ -681,13 +681,13 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
<TextBlock
|
||||
x:Name="tipHeaderType"
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbHeaderType}" />
|
||||
@@ -695,7 +695,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbRequestHost}" />
|
||||
@@ -704,13 +704,13 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<TextBlock
|
||||
x:Name="tipRequestHost"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbRequestHost}" />
|
||||
@@ -718,7 +718,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPath}" />
|
||||
@@ -727,13 +727,13 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<TextBlock
|
||||
x:Name="tipPath"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPath}" />
|
||||
@@ -760,7 +760,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbStreamSecurity}" />
|
||||
@@ -769,7 +769,7 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -791,7 +791,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSNI}" />
|
||||
@@ -800,14 +800,14 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbFingerprint}" />
|
||||
@@ -816,14 +816,14 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
IsEditable="True"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAlpn}" />
|
||||
@@ -832,13 +832,13 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAllowInsecure}" />
|
||||
@@ -847,7 +847,7 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="100"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -869,7 +869,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSNI}" />
|
||||
@@ -878,14 +878,14 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbFingerprint}" />
|
||||
@@ -894,14 +894,14 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
IsEditable="True"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbPublicKey}" />
|
||||
@@ -910,14 +910,14 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbShortId}" />
|
||||
@@ -926,14 +926,14 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSpiderX}" />
|
||||
@@ -942,7 +942,7 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource ServerItemMargin}"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
|
||||
@@ -267,7 +267,7 @@ namespace v2rayN.Views
|
||||
private void btnGUID_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtId.Text =
|
||||
txtId5.Text = Utils.GetGUID();
|
||||
txtId5.Text = Utils.GetGuid();
|
||||
}
|
||||
|
||||
private void SetHeaderType()
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<DockPanel Margin="16">
|
||||
<DockPanel Margin="8" DockPanel.Dock="Bottom">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<DockPanel Margin="{StaticResource Margin8}" DockPanel.Dock="Bottom">
|
||||
<Button
|
||||
Width="100"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||
Content="{x:Static resx:ResUI.menuClose}"
|
||||
DockPanel.Dock="Right"
|
||||
@@ -35,14 +35,14 @@
|
||||
|
||||
<TextBlock
|
||||
x:Name="txtMsg"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource ToolbarTextBlock}" />
|
||||
</DockPanel>
|
||||
|
||||
<StackPanel>
|
||||
<materialDesign:Card Width="Auto" Margin="8">
|
||||
<Grid Margin="8">
|
||||
<materialDesign:Card Width="Auto" Margin="{StaticResource Margin8}">
|
||||
<Grid Margin="{StaticResource Margin8}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -56,14 +56,14 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Style="{StaticResource ModuleTitle}"
|
||||
Text="{x:Static resx:ResUI.menuLocalBackupAndRestore}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.menuLocalBackup}" />
|
||||
@@ -71,7 +71,7 @@
|
||||
x:Name="menuLocalBackup"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Static resx:ResUI.menuLocalBackup}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
@@ -84,7 +84,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.menuLocalRestore}" />
|
||||
@@ -92,14 +92,14 @@
|
||||
x:Name="menuLocalRestore"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Static resx:ResUI.menuLocalRestore}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</Grid>
|
||||
</materialDesign:Card>
|
||||
<materialDesign:Card Width="Auto" Margin="8">
|
||||
<Grid Margin="8">
|
||||
<materialDesign:Card Width="Auto" Margin="{StaticResource Margin8}">
|
||||
<Grid Margin="{StaticResource Margin8}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -115,7 +115,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Style="{StaticResource ModuleTitle}"
|
||||
Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" />
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
HorizontalAlignment="Right"
|
||||
StaysOpen="True"
|
||||
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
||||
<StackPanel Margin="16">
|
||||
<StackPanel Margin="{StaticResource Margin8}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -140,7 +140,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvWebDavUrl}" />
|
||||
@@ -149,7 +149,7 @@
|
||||
x:Name="txtWebDavUrl"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource DefTextBox}"
|
||||
TextWrapping="Wrap" />
|
||||
@@ -157,7 +157,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvWebDavUserName}" />
|
||||
@@ -166,14 +166,14 @@
|
||||
x:Name="txtWebDavUserName"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvWebDavPassword}" />
|
||||
@@ -182,14 +182,14 @@
|
||||
x:Name="txtWebDavPassword"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvWebDavDirName}" />
|
||||
@@ -198,7 +198,7 @@
|
||||
x:Name="txtWebDavDirName"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
x:Name="menuWebDavCheck"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Static resx:ResUI.LvWebDavCheck}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
@@ -218,7 +218,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.menuRemoteBackup}" />
|
||||
@@ -226,7 +226,7 @@
|
||||
x:Name="menuRemoteBackup"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Static resx:ResUI.menuRemoteBackup}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
@@ -238,7 +238,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.menuRemoteRestore}" />
|
||||
@@ -246,7 +246,7 @@
|
||||
x:Name="menuRemoteRestore"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Static resx:ResUI.menuRemoteRestore}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
|
||||
@@ -15,27 +15,27 @@
|
||||
Style="{StaticResource ViewGlobal}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<DockPanel Margin="16">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Right"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsEnableCheckPreReleaseUpdate}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnableCheckPreReleaseUpdate"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<Button
|
||||
x:Name="btnCheckUpdate"
|
||||
Width="100"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.menuCheckUpdate}"
|
||||
IsCancel="True"
|
||||
IsDefault="True"
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
<Button
|
||||
Width="100"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||
Content="{x:Static resx:ResUI.menuClose}"
|
||||
@@ -67,7 +67,7 @@
|
||||
<Border
|
||||
Width="500"
|
||||
Height="50"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Padding="0"
|
||||
VerticalAlignment="Center">
|
||||
<Grid>
|
||||
@@ -82,7 +82,7 @@
|
||||
<ToggleButton
|
||||
x:Name="togAutoRefresh"
|
||||
Grid.Column="0"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="{Binding IsSelected}" />
|
||||
<TextBlock
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
x:TypeArguments="vms:ClashConnectionsViewModel"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<DockPanel Margin="2">
|
||||
<DockPanel Margin="{StaticResource Margin4}">
|
||||
<WrapPanel
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Top"
|
||||
Orientation="Horizontal">
|
||||
@@ -23,21 +23,21 @@
|
||||
<TextBox
|
||||
x:Name="txtHostFilter"
|
||||
Width="200"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalContentAlignment="Center"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.ConnectionsHostFilterTitle}"
|
||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSorting}" />
|
||||
<ComboBox
|
||||
x:Name="cmbSorting"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource DefComboBox}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingUpSpeed}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDownSpeed}" />
|
||||
@@ -51,20 +51,20 @@
|
||||
x:Name="btnConnectionCloseAll"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuConnectionCloseAll}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Close" />
|
||||
</Button>
|
||||
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAutoRefresh}" />
|
||||
<ToggleButton
|
||||
x:Name="togAutoRefresh"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
HorizontalAlignment="Left" />
|
||||
</WrapPanel>
|
||||
|
||||
|
||||
@@ -20,22 +20,22 @@
|
||||
<converters:DelayColorConverter x:Key="DelayColorConverter" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<DockPanel Margin="2">
|
||||
<DockPanel Margin="{StaticResource Margin4}">
|
||||
<WrapPanel
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Top"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.menuRulemode}" />
|
||||
<ComboBox
|
||||
x:Name="cmbRulemode"
|
||||
Width="80"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource DefComboBox}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeGlobal}" />
|
||||
@@ -43,14 +43,14 @@
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSorting}" />
|
||||
<ComboBox
|
||||
x:Name="cmbSorting"
|
||||
Width="60"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource DefComboBox}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingName}" />
|
||||
@@ -61,7 +61,7 @@
|
||||
x:Name="menuProxiesReload"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuProxiesReload}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Reload" />
|
||||
@@ -71,26 +71,26 @@
|
||||
x:Name="menuProxiesDelaytest"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuProxiesDelaytest}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="LightningBolt" />
|
||||
</Button>
|
||||
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAutoRefresh}" />
|
||||
<ToggleButton
|
||||
x:Name="togAutoRefresh"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
HorizontalAlignment="Left" />
|
||||
</WrapPanel>
|
||||
<DockPanel>
|
||||
<ListView
|
||||
x:Name="lstProxyGroups"
|
||||
Margin="0,0,5,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
BorderThickness="0"
|
||||
DockPanel.Dock="Left"
|
||||
ItemContainerStyle="{StaticResource lvItemSelected}"
|
||||
@@ -106,10 +106,10 @@
|
||||
<DataTemplate>
|
||||
<Border
|
||||
Width="160"
|
||||
Margin="4,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Padding="0">
|
||||
<DockPanel>
|
||||
<Grid Grid.Column="0" Margin="4">
|
||||
<Grid Grid.Column="0" Margin="{StaticResource Margin4}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
@@ -162,7 +162,7 @@
|
||||
CornerRadius="4"
|
||||
DockPanel.Dock="Left"
|
||||
Visibility="{Binding Path=isActive, Converter={StaticResource BoolToVisConverter}}" />
|
||||
<Grid Margin="4">
|
||||
<Grid Margin="{StaticResource Margin4}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="2*" />
|
||||
<RowDefinition Height="1*" />
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="8">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Center"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
@@ -37,7 +37,7 @@
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbCancel}"
|
||||
Cursor="Hand"
|
||||
IsCancel="true"
|
||||
@@ -47,15 +47,15 @@
|
||||
<TabControl HorizontalContentAlignment="Left">
|
||||
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDns}">
|
||||
<DockPanel Margin="{StaticResource SettingItemMargin}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsRemoteDNS}" />
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsObjectDoc_Click">
|
||||
@@ -65,7 +65,7 @@
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4V2ray"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand"
|
||||
Style="{StaticResource DefButton}" />
|
||||
@@ -74,39 +74,39 @@
|
||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsUseSystemHosts}" />
|
||||
<ToggleButton
|
||||
x:Name="togUseSystemHosts"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Freedom"
|
||||
Width="150"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainDNSAddress"
|
||||
Width="150"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
IsEditable="True"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
<TextBox
|
||||
x:Name="txtnormalDNS"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Stretch"
|
||||
materialDesign:HintAssist.Hint="HTTP/SOCKS"
|
||||
AcceptsReturn="True"
|
||||
@@ -126,10 +126,10 @@
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}">
|
||||
<DockPanel Margin="{StaticResource SettingItemMargin}">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsSingboxObjectDoc_Click">
|
||||
@@ -139,7 +139,7 @@
|
||||
</TextBlock>
|
||||
<Button
|
||||
x:Name="btnImportDefConfig4Singbox"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Content="{x:Static resx:ResUI.TbSettingDnsImportDefConfig}"
|
||||
Cursor="Hand"
|
||||
Style="{StaticResource DefButton}" />
|
||||
@@ -148,33 +148,33 @@
|
||||
<WrapPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainStrategy4Out}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Out"
|
||||
Width="150"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsDomainDNSAddress}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainDNSAddress2"
|
||||
Width="150"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
Margin="{StaticResource Margin8}"
|
||||
IsEditable="True"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
</WrapPanel>
|
||||
|
||||
<Grid Margin="{StaticResource SettingItemMargin}">
|
||||
<Grid Margin="{StaticResource Margin8}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
|
||||
@@ -23,16 +23,16 @@
|
||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="8">
|
||||
<DockPanel Margin="{StaticResource Margin8}">
|
||||
<StackPanel
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Center"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
x:Name="btnReset"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbReset}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
<Button
|
||||
@@ -44,7 +44,7 @@
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbCancel}"
|
||||
Cursor="Hand"
|
||||
IsCancel="true"
|
||||
@@ -77,14 +77,14 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource ModuleTitle}"
|
||||
Text="{x:Static resx:ResUI.TbGlobalHotkeySetting}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbDisplayGUI}" />
|
||||
@@ -93,7 +93,7 @@
|
||||
x:Name="txtGlobalHotkey0"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
IsReadOnly="True"
|
||||
@@ -103,7 +103,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbClearSystemProxy}" />
|
||||
@@ -111,7 +111,7 @@
|
||||
x:Name="txtGlobalHotkey1"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
IsReadOnly="True"
|
||||
@@ -121,7 +121,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSetSystemProxy}" />
|
||||
@@ -129,7 +129,7 @@
|
||||
x:Name="txtGlobalHotkey2"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
IsReadOnly="True"
|
||||
@@ -138,7 +138,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbNotChangeSystemProxy}" />
|
||||
@@ -146,7 +146,7 @@
|
||||
x:Name="txtGlobalHotkey3"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
IsReadOnly="True"
|
||||
@@ -155,7 +155,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSystemProxyPac}" />
|
||||
@@ -163,7 +163,7 @@
|
||||
x:Name="txtGlobalHotkey4"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
IsReadOnly="True"
|
||||
@@ -173,7 +173,7 @@
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbGlobalHotkeySettingTip}" />
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Server" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuServers}" />
|
||||
@@ -114,7 +114,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="BookClockOutline" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSubscription}" />
|
||||
@@ -149,7 +149,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="SettingsOutline" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSetting}" />
|
||||
@@ -201,7 +201,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Reload" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuReload}" />
|
||||
@@ -215,7 +215,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Update" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuCheckUpdate}" />
|
||||
@@ -229,7 +229,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="HelpCircleOutline" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuHelp}" />
|
||||
@@ -243,7 +243,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="VolumeHigh" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuPromotion}" />
|
||||
@@ -257,7 +257,7 @@
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Minimize" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuClose}" />
|
||||
@@ -313,11 +313,7 @@
|
||||
<TabItem x:Name="tabMsgView1">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="MessageTextOutline" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="MessageTextOutline" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
@@ -328,11 +324,7 @@
|
||||
<TabItem x:Name="tabClashProxies1">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="ArrowDecisionOutline" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="ArrowDecisionOutline" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
@@ -343,11 +335,7 @@
|
||||
<TabItem x:Name="tabClashConnections1">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="LanConnect" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="LanConnect" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
@@ -366,11 +354,7 @@
|
||||
<TabItem x:Name="tabProfiles2">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="Server" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="Server" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
@@ -381,11 +365,7 @@
|
||||
<TabItem x:Name="tabMsgView2">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="MessageTextOutline" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="MessageTextOutline" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
@@ -396,11 +376,7 @@
|
||||
<TabItem x:Name="tabClashProxies2">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="ArrowDecisionOutline" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="ArrowDecisionOutline" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
@@ -411,11 +387,7 @@
|
||||
<TabItem x:Name="tabClashConnections2">
|
||||
<TabItem.Header>
|
||||
<StackPanel>
|
||||
<materialDesign:PackIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
Kind="LanConnect" />
|
||||
<materialDesign:PackIcon HorizontalAlignment="Center" Kind="LanConnect" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
|
||||
@@ -41,26 +41,29 @@ namespace v2rayN.Views
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||
|
||||
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
switch (_config.uiItem.mainGirdOrientation)
|
||||
{
|
||||
tabProfiles.Content ??= new ProfilesView();
|
||||
tabMsgView.Content ??= new MsgView();
|
||||
tabClashProxies.Content ??= new ClashProxiesView();
|
||||
tabClashConnections.Content ??= new ClashConnectionsView();
|
||||
}
|
||||
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
|
||||
{
|
||||
tabProfiles1.Content ??= new ProfilesView();
|
||||
tabMsgView1.Content ??= new MsgView();
|
||||
tabClashProxies1.Content ??= new ClashProxiesView();
|
||||
tabClashConnections1.Content ??= new ClashConnectionsView();
|
||||
}
|
||||
else
|
||||
{
|
||||
tabProfiles2.Content ??= new ProfilesView();
|
||||
tabMsgView2.Content ??= new MsgView();
|
||||
tabClashProxies2.Content ??= new ClashProxiesView();
|
||||
tabClashConnections2.Content ??= new ClashConnectionsView();
|
||||
case EGirdOrientation.Horizontal:
|
||||
tabProfiles.Content ??= new ProfilesView();
|
||||
tabMsgView.Content ??= new MsgView();
|
||||
tabClashProxies.Content ??= new ClashProxiesView();
|
||||
tabClashConnections.Content ??= new ClashConnectionsView();
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Vertical:
|
||||
tabProfiles1.Content ??= new ProfilesView();
|
||||
tabMsgView1.Content ??= new MsgView();
|
||||
tabClashProxies1.Content ??= new ClashProxiesView();
|
||||
tabClashConnections1.Content ??= new ClashConnectionsView();
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Tab:
|
||||
default:
|
||||
tabProfiles2.Content ??= new ProfilesView();
|
||||
tabMsgView2.Content ??= new MsgView();
|
||||
tabClashProxies2.Content ??= new ClashProxiesView();
|
||||
tabClashConnections2.Content ??= new ClashConnectionsView();
|
||||
break;
|
||||
}
|
||||
pbTheme.Content ??= new ThemeSettingView();
|
||||
|
||||
@@ -99,30 +102,35 @@ namespace v2rayN.Views
|
||||
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
||||
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
switch (_config.uiItem.mainGirdOrientation)
|
||||
{
|
||||
gridMain.Visibility = Visibility.Visible;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections.Visibility).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain.SelectedIndex).DisposeWith(disposables);
|
||||
}
|
||||
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
|
||||
{
|
||||
gridMain1.Visibility = Visibility.Visible;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies1.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections1.Visibility).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain1.SelectedIndex).DisposeWith(disposables);
|
||||
}
|
||||
else
|
||||
{
|
||||
gridMain2.Visibility = Visibility.Visible;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies2.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections2.Visibility).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
|
||||
case EGirdOrientation.Horizontal:
|
||||
gridMain.Visibility = Visibility.Visible;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabMsgView.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections.Visibility).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain.SelectedIndex).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Vertical:
|
||||
gridMain1.Visibility = Visibility.Visible;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabMsgView1.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies1.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections1.Visibility).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain1.SelectedIndex).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EGirdOrientation.Tab:
|
||||
default:
|
||||
gridMain2.Visibility = Visibility.Visible;
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies2.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections2.Visibility).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
|
||||
if (!_config.guiItem.enableHWA)
|
||||
{
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
x:TypeArguments="vms:MsgViewModel"
|
||||
Style="{StaticResource ViewGlobal}"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="2">
|
||||
<DockPanel Margin="{StaticResource Margin4}">
|
||||
<WrapPanel
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Top"
|
||||
Orientation="Horizontal">
|
||||
@@ -23,7 +23,7 @@
|
||||
<ComboBox
|
||||
x:Name="cmbMsgFilter"
|
||||
Width="200"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}"
|
||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||
IsEditable="True"
|
||||
@@ -32,7 +32,7 @@
|
||||
x:Name="btnCopy"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuMsgViewCopyAll}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="ContentCopy" />
|
||||
@@ -41,29 +41,29 @@
|
||||
x:Name="btnClear"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuMsgViewClear}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Delete" />
|
||||
</Button>
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAutoRefresh}" />
|
||||
<ToggleButton
|
||||
x:Name="togAutoRefresh"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="True" />
|
||||
<TextBlock
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbAutoScrollToEnd}" />
|
||||
<ToggleButton
|
||||
x:Name="togScrollToEnd"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="True" />
|
||||
</WrapPanel>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -85,6 +85,10 @@ namespace v2rayN.Views
|
||||
{
|
||||
cmbSubConvertUrl.Items.Add(it);
|
||||
});
|
||||
Global.GeoFilesSources.ForEach(it =>
|
||||
{
|
||||
cmbGetFilesSourceUrl.Items.Add(it);
|
||||
});
|
||||
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
|
||||
{
|
||||
cmbMainGirdOrientation.Items.Add(it.ToString());
|
||||
@@ -145,6 +149,7 @@ namespace v2rayN.Views
|
||||
this.Bind(ViewModel, vm => vm.EnableHWA, v => v.togEnableHWA.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.MainGirdOrientation, v => v.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.GeoFileSourceUrl, v => v.cmbGetFilesSourceUrl.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.notProxyLocalAddress, v => v.tognotProxyLocalAddress.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<DockPanel>
|
||||
<WrapPanel Margin="2" DockPanel.Dock="Top">
|
||||
<WrapPanel Margin="{StaticResource Margin4}" DockPanel.Dock="Top">
|
||||
<ListBox
|
||||
x:Name="lstGroup"
|
||||
MaxHeight="200"
|
||||
@@ -39,7 +39,7 @@
|
||||
x:Name="btnEditSub"
|
||||
Width="30"
|
||||
Height="30"
|
||||
Margin="4,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuSubEdit}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Edit" />
|
||||
@@ -48,7 +48,7 @@
|
||||
x:Name="btnAddSub"
|
||||
Width="30"
|
||||
Height="30"
|
||||
Margin="4,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuSubAdd}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Plus" />
|
||||
@@ -58,7 +58,7 @@
|
||||
x:Name="btnAutofitColumnWidth"
|
||||
Width="30"
|
||||
Height="30"
|
||||
Margin="20,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||
ToolTip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="ArrowSplitVertical" />
|
||||
@@ -66,7 +66,7 @@
|
||||
<TextBox
|
||||
x:Name="txtServerFilter"
|
||||
Width="200"
|
||||
Margin="4,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
VerticalContentAlignment="Center"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
|
||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
d:DesignWidth="300"
|
||||
Style="{StaticResource ViewGlobal}"
|
||||
mc:Ignorable="d">
|
||||
<Grid Margin="30">
|
||||
<Grid Margin="32">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -38,7 +38,7 @@
|
||||
<Button
|
||||
Grid.Row="2"
|
||||
Width="100"
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||
Content="{x:Static resx:ResUI.TbConfirm}"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel>
|
||||
<Grid Margin="8" DockPanel.Dock="Top">
|
||||
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -41,7 +41,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvRemarks}" />
|
||||
@@ -50,20 +50,20 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnabled"
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="outboundTag" />
|
||||
@@ -72,13 +72,13 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
MaxDropDownHeight="1000"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbRuleMatchingTips}" />
|
||||
@@ -86,7 +86,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="port" />
|
||||
@@ -95,13 +95,13 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkRuleobjectDoc_Click">
|
||||
@@ -113,7 +113,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="protocol" />
|
||||
@@ -121,7 +121,7 @@
|
||||
x:Name="clbProtocol"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" />
|
||||
@@ -129,7 +129,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="inboundTag" />
|
||||
@@ -137,14 +137,14 @@
|
||||
x:Name="clbInboundTag"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="network" />
|
||||
@@ -153,21 +153,21 @@
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
MaxDropDownHeight="1000"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="2"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbRoutingTips}" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Right"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
@@ -188,14 +188,14 @@
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbCancel}"
|
||||
Cursor="Hand"
|
||||
IsCancel="true"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid Margin="{StaticResource SettingItemMargin}">
|
||||
<Grid Margin="{StaticResource Margin8}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<Button x:Name="menuRuleAdd">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Plus" />
|
||||
<TextBlock Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.menuRuleAdd}" />
|
||||
@@ -42,7 +42,7 @@
|
||||
<Button x:Name="menuImportRulesFromFile">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Import" />
|
||||
<TextBlock Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.menuImportRulesFromFile}" />
|
||||
@@ -52,7 +52,7 @@
|
||||
<Button x:Name="menuImportRulesFromClipboard">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Import" />
|
||||
<TextBlock Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.menuImportRulesFromClipboard}" />
|
||||
@@ -62,7 +62,7 @@
|
||||
<Button x:Name="menuImportRulesFromUrl">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Margin="0,0,8,0"
|
||||
Margin="{StaticResource MarginRight8}"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Import" />
|
||||
<TextBlock Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.menuImportRulesFromUrl}" />
|
||||
@@ -72,7 +72,7 @@
|
||||
</ToolBarTray>
|
||||
|
||||
<StackPanel
|
||||
Margin="8"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Right"
|
||||
DockPanel.Dock="Bottom"
|
||||
Orientation="Horizontal">
|
||||
@@ -85,14 +85,14 @@
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
Margin="{StaticResource MarginLeftRight8}"
|
||||
Content="{x:Static resx:ResUI.TbCancel}"
|
||||
Cursor="Hand"
|
||||
IsCancel="true"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid Margin="8" DockPanel.Dock="Top">
|
||||
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -109,7 +109,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvRemarks}" />
|
||||
@@ -123,7 +123,7 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="300"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
@@ -131,14 +131,14 @@
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvSort}" />
|
||||
<TextBox
|
||||
x:Name="txtSort"
|
||||
Width="100"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
@@ -147,7 +147,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbdomainStrategy}" />
|
||||
@@ -158,24 +158,24 @@
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
<TextBlock
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" />
|
||||
<ComboBox
|
||||
x:Name="cmbdomainStrategy4Singbox"
|
||||
Width="200"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvUrl}" />
|
||||
@@ -184,7 +184,7 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="600"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}"
|
||||
@@ -193,7 +193,7 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvCustomIcon}" />
|
||||
@@ -202,7 +202,7 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="600"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}"
|
||||
@@ -211,14 +211,14 @@
|
||||
x:Name="btnBrowseCustomIcon"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="2,0,8,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkCustomRulesetPath4Singbox">
|
||||
@@ -231,7 +231,7 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="600"
|
||||
Margin="4"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}"
|
||||
@@ -240,7 +240,7 @@
|
||||
x:Name="btnBrowseCustomRulesetPath4Singbox"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="2,0,8,0"
|
||||
Margin="{StaticResource MarginLeftRight4}"
|
||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</Grid>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user