diff --git a/.github/update.log b/.github/update.log index 5822e82a3d..45a9e7a025 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1144,3 +1144,4 @@ Update On Sat Oct 4 20:34:01 CEST 2025 Update On Sun Oct 5 20:34:00 CEST 2025 Update On Mon Oct 6 20:37:45 CEST 2025 Update On Tue Oct 7 20:41:59 CEST 2025 +Update On Wed Oct 8 20:42:18 CEST 2025 diff --git a/clash-nyanpasu/backend/tauri/src/ipc.rs b/clash-nyanpasu/backend/tauri/src/ipc.rs index dde10f2791..b268dda22f 100644 --- a/clash-nyanpasu/backend/tauri/src/ipc.rs +++ b/clash-nyanpasu/backend/tauri/src/ipc.rs @@ -985,38 +985,6 @@ pub async fn get_clash_ws_connections_state( Ok(ws_connector.state()) } -/// Move window to another monitor -#[tauri::command] -#[specta::specta] -pub fn move_window_to_other_monitor( - window: tauri::Window, - target_monitor_index: usize, -) -> Result<()> { - crate::utils::window_manager::move_window_to_other_monitor(window, target_monitor_index)?; - Ok(()) -} - -/// Center window on current monitor -#[tauri::command] -#[specta::specta] -pub fn center_window(window: tauri::Window) -> Result<()> { - crate::utils::window_manager::center_window(&window)?; - Ok(()) -} - -/// Get available monitors -#[tauri::command] -#[specta::specta] -pub fn get_available_monitors( - window: tauri::Window, -) -> Result> { - let monitors = crate::utils::window_manager::get_available_monitors(window)?; - Ok(monitors - .iter() - .map(|(id, monitor)| ((*id, monitor)).into()) - .collect()) -} - // Updater block #[derive(Default, Clone, serde::Serialize, serde::Deserialize, specta::Type)] diff --git a/clash-nyanpasu/backend/tauri/src/lib.rs b/clash-nyanpasu/backend/tauri/src/lib.rs index b620708bce..c438265685 100644 --- a/clash-nyanpasu/backend/tauri/src/lib.rs +++ b/clash-nyanpasu/backend/tauri/src/lib.rs @@ -272,10 +272,6 @@ pub fn run() -> std::io::Result<()> { ipc::get_core_dir, // clash layer ipc::get_clash_ws_connections_state, - // window management - ipc::move_window_to_other_monitor, - ipc::center_window, - ipc::get_available_monitors, // updater layer ipc::check_update, ]) diff --git a/clash-nyanpasu/backend/tauri/src/utils/mod.rs b/clash-nyanpasu/backend/tauri/src/utils/mod.rs index 86bb526568..6c117abc24 100644 --- a/clash-nyanpasu/backend/tauri/src/utils/mod.rs +++ b/clash-nyanpasu/backend/tauri/src/utils/mod.rs @@ -17,7 +17,6 @@ pub mod open; pub mod dock; pub mod sudo; -pub mod window_manager; #[cfg(test)] #[cfg(windows)] diff --git a/clash-nyanpasu/backend/tauri/src/utils/window_manager.rs b/clash-nyanpasu/backend/tauri/src/utils/window_manager.rs deleted file mode 100644 index ee9540ff37..0000000000 --- a/clash-nyanpasu/backend/tauri/src/utils/window_manager.rs +++ /dev/null @@ -1,204 +0,0 @@ -//! Window management utilities for multi-monitor setups with different scaling factors -use display_info::DisplayInfo; -use serde::{Deserialize, Serialize}; -use specta::Type; -use tauri::{Monitor, PhysicalPosition, PhysicalSize, Position, Size, Window}; - -/// Simplified monitor information for IPC -#[derive(Debug, Clone, Serialize, Deserialize, Type)] -pub struct MonitorInfo { - pub id: usize, - pub name: String, - pub position: (i32, i32), - pub size: (u32, u32), - pub scale_factor: f64, -} - -impl From<(usize, &Monitor)> for MonitorInfo { - fn from((id, monitor): (usize, &Monitor)) -> Self { - let position = monitor.position(); - let size = monitor.size(); - Self { - id, - name: format!("Monitor {}", id), - position: (position.x, position.y), - size: (size.width, size.height), - scale_factor: monitor.scale_factor(), - } - } -} - -/// Get the scale factor for a specific monitor -fn get_monitor_scale_factor(monitor: &Monitor) -> f64 { - // Try to get the scale factor from the display info - if let Ok(displays) = DisplayInfo::all() { - for display in displays { - // Match the monitor by position and size - let monitor_pos = monitor.position(); - let monitor_size = monitor.size(); - - if display.x == monitor_pos.x - && display.y == monitor_pos.y - && display.width as u32 == monitor_size.width - && display.height as u32 == monitor_size.height - { - return display.scale_factor as f64; - } - } - } - - // Fallback to the monitor's scale factor if we can't find it in display info - monitor.scale_factor() -} - -/// Move window to another monitor while correctly handling different scaling factors -pub fn move_window_to_other_monitor( - window: Window, - target_monitor_index: usize, -) -> tauri::Result<()> { - let monitors = get_available_monitors(window.clone())?; - - let (_index, target_monitor) = - monitors - .get(target_monitor_index) - .ok_or(tauri::Error::InvalidArgs( - "target_monitor_index", - "Index out of bounds", - serde_json::Error::io(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - "Index out of bounds", - )), - ))?; - - // Get current monitor - let current_monitor = window - .current_monitor()? - .unwrap_or_else(|| target_monitor.clone()); - - // Get scale factors for current and target monitors - let current_scale_factor = get_monitor_scale_factor(¤t_monitor); - let target_scale_factor = get_monitor_scale_factor(target_monitor); - - // Get current window size - let window_size = window.outer_size()?; - - // Calculate scaled size for target monitor - let scale_ratio = current_scale_factor / target_scale_factor; - let target_width = (window_size.width as f64 * scale_ratio).round() as u32; - let target_height = (window_size.height as f64 * scale_ratio).round() as u32; - - // Set window size first to prevent flickering - window.set_size(Size::Physical(PhysicalSize { - width: target_width, - height: target_height, - }))?; - - // Move window to target monitor position - let pos = target_monitor.position(); - window.set_position(Position::Physical(PhysicalPosition { x: pos.x, y: pos.y }))?; - - Ok(()) -} - -/// Resize window while correctly handling monitor scaling factors -fn resize_window(window: &Window, screen_share: f64) -> tauri::Result<()> { - let monitor = window.current_monitor().unwrap().unwrap(); - let monitor_size = monitor.size(); - - // Get the monitor's scale factor - let scale_factor = get_monitor_scale_factor(&monitor); - - // Calculate size accounting for scale factor - let scaled_size: PhysicalSize = PhysicalSize { - width: ((monitor_size.width as f64 * screen_share) / scale_factor).round() as u32, - height: ((monitor_size.height as f64 * screen_share) / scale_factor).round() as u32, - }; - - window.set_size(Size::Physical(scaled_size))?; - Ok(()) -} - -/// Center window on current monitor while correctly handling scaling factors -#[cfg(windows)] -pub fn center_window(window: &Window) -> tauri::Result<()> { - use windows_sys::Win32::{ - Foundation::RECT, - UI::WindowsAndMessaging::{SPI_GETWORKAREA, SystemParametersInfoW}, - }; - - // Get current monitor - let monitor = window.current_monitor()?.ok_or(tauri::Error::InvalidArgs( - "current_monitor", - "No current monitor", - serde_json::Error::io(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - "No current monitor", - )), - ))?; - let scale_factor = get_monitor_scale_factor(&monitor); - - // Get work area - let mut work_area = RECT { - left: 0, - top: 0, - right: 0, - bottom: 0, - }; - unsafe { - SystemParametersInfoW(SPI_GETWORKAREA, 0, &mut work_area as *mut _ as *mut _, 0); - } - - let work_area_width = (work_area.right - work_area.left) as u32; - let work_area_height = (work_area.bottom - work_area.top) as u32; - let work_area_x = work_area.left as i32; - let work_area_y = work_area.top as i32; - - let window_size = window.outer_size()?; - - // Adjust for scale factor - let adjusted_window_width = (window_size.width as f64 / scale_factor).round() as i32; - let adjusted_window_height = (window_size.height as f64 / scale_factor).round() as i32; - - let new_x = work_area_x + (work_area_width as i32 - adjusted_window_width) / 2; - let new_y = work_area_y + (work_area_height as i32 - adjusted_window_height) / 2; - - window.set_position(Position::Physical(PhysicalPosition { x: new_x, y: new_y }))?; - Ok(()) -} - -#[cfg(target_os = "macos")] -pub fn center_window(window: &Window) -> tauri::Result<()> { - window.center(); - Ok(()) -} - -#[cfg(target_os = "linux")] -pub fn center_window(window: &Window) -> tauri::Result<()> { - window.center(); - Ok(()) -} - -/// Get available monitors sorted by position -pub fn get_available_monitors( - window: tauri::Window, -) -> tauri::Result> { - let mut monitors = window.available_monitors()?; - monitors.sort_by(|a, b| { - let a_pos = a.position(); - let b_pos = b.position(); - let a_size = a.size(); - let b_size = b.size(); - let a_val = - (a_pos.y + 200) * 10 / a_size.height as i32 + (a_pos.x + 300) / a_size.width as i32; - let b_val = - (b_pos.y + 200) * 10 / b_size.height as i32 + (b_pos.x + 300) / b_size.width as i32; - - a_val.cmp(&b_val) - }); - - monitors - .iter() - .enumerate() - .map(|(i, m)| Ok((i, m.clone()))) - .collect() -} diff --git a/clash-nyanpasu/frontend/interface/src/ipc/bindings.ts b/clash-nyanpasu/frontend/interface/src/ipc/bindings.ts index 6232dbb8a3..a42d64d1a3 100644 --- a/clash-nyanpasu/frontend/interface/src/ipc/bindings.ts +++ b/clash-nyanpasu/frontend/interface/src/ipc/bindings.ts @@ -720,49 +720,6 @@ export const commands = { else return { status: 'error', error: e as any } } }, - /** - * Move window to another monitor - */ - async moveWindowToOtherMonitor( - targetMonitorIndex: number, - ): Promise> { - try { - return { - status: 'ok', - data: await TAURI_INVOKE('move_window_to_other_monitor', { - targetMonitorIndex, - }), - } - } catch (e) { - if (e instanceof Error) throw e - else return { status: 'error', error: e as any } - } - }, - /** - * Center window on current monitor - */ - async centerWindow(): Promise> { - try { - return { status: 'ok', data: await TAURI_INVOKE('center_window') } - } catch (e) { - if (e instanceof Error) throw e - else return { status: 'error', error: e as any } - } - }, - /** - * Get available monitors - */ - async getAvailableMonitors(): Promise> { - try { - return { - status: 'ok', - data: await TAURI_INVOKE('get_available_monitors'), - } - } catch (e) { - if (e instanceof Error) throw e - else return { status: 'error', error: e as any } - } - }, async checkUpdate(): Promise> { try { return { status: 'ok', data: await TAURI_INVOKE('check_update') } @@ -1216,16 +1173,6 @@ export type MergeProfileBuilder = { */ updated: number | null } -/** - * Simplified monitor information for IPC - */ -export type MonitorInfo = { - id: number - name: string - position: [number, number] - size: [number, number] - scale_factor: number -} export type NetworkStatisticWidgetConfig = | { kind: 'disabled' } | { kind: 'enabled'; value: StatisticWidgetVariant } diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index 1ba7a1cbba..09fbdd8745 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -32,7 +32,7 @@ "country-emoji": "1.5.6", "dayjs": "1.11.18", "framer-motion": "12.23.22", - "i18next": "25.5.2", + "i18next": "25.5.3", "jotai": "2.15.0", "json-schema": "0.4.0", "material-react-table": "3.2.1", @@ -56,11 +56,11 @@ "@csstools/normalize.css": "12.1.1", "@emotion/babel-plugin": "11.13.5", "@emotion/react": "11.14.0", - "@iconify/json": "2.2.392", + "@iconify/json": "2.2.393", "@monaco-editor/react": "4.7.0", "@tanstack/react-query": "5.90.2", "@tanstack/react-router": "1.132.47", - "@tanstack/react-router-devtools": "1.132.47", + "@tanstack/react-router-devtools": "1.132.50", "@tanstack/router-plugin": "1.132.47", "@tauri-apps/plugin-clipboard-manager": "2.3.0", "@tauri-apps/plugin-dialog": "2.4.0", @@ -93,6 +93,6 @@ "vite-plugin-sass-dts": "1.3.31", "vite-plugin-svgr": "4.5.0", "vite-tsconfig-paths": "5.1.4", - "zod": "4.1.11" + "zod": "4.1.12" } } diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index bc88afe588..913fb37b44 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.14", - "mihomo_alpha": "alpha-c13549f", + "mihomo_alpha": "alpha-da69b19", "clash_rs": "v0.9.1", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.9.1-alpha+sha.f613a53" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-10-06T22:20:51.197Z" + "updated_at": "2025-10-07T22:20:54.276Z" } diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index 24003a332c..85a995d80c 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -253,7 +253,7 @@ importers: version: 4.1.13 '@tanstack/router-zod-adapter': specifier: 1.81.5 - version: 1.81.5(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.1.11) + version: 1.81.5(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.1.12) '@tauri-apps/api': specifier: 2.8.0 version: 2.8.0 @@ -279,8 +279,8 @@ importers: specifier: 12.23.22 version: 12.23.22(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) i18next: - specifier: 25.5.2 - version: 25.5.2(typescript@5.9.2) + specifier: 25.5.3 + version: 25.5.3(typescript@5.9.2) jotai: specifier: 2.15.0 version: 2.15.0(@babel/core@7.28.4)(@babel/template@7.27.2)(@types/react@19.1.14)(react@19.1.1) @@ -313,7 +313,7 @@ importers: version: 8.0.0(5034abb0a696b1128593edad6cde9ffd) react-i18next: specifier: 15.7.4 - version: 15.7.4(i18next@25.5.2(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) + version: 15.7.4(i18next@25.5.3(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) react-markdown: specifier: 10.1.0 version: 10.1.0(@types/react@19.1.14)(react@19.1.1) @@ -346,8 +346,8 @@ importers: specifier: 11.14.0 version: 11.14.0(@types/react@19.1.14)(react@19.1.1) '@iconify/json': - specifier: 2.2.392 - version: 2.2.392 + specifier: 2.2.393 + version: 2.2.393 '@monaco-editor/react': specifier: 4.7.0 version: 4.7.0(monaco-editor@0.54.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -358,8 +358,8 @@ importers: specifier: 1.132.47 version: 1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@tanstack/react-router-devtools': - specifier: 1.132.47 - version: 1.132.47(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) + specifier: 1.132.50 + version: 1.132.50(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass-embedded@1.93.2)(sass@1.93.2)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) '@tanstack/router-plugin': specifier: 1.132.47 version: 1.132.47(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -457,8 +457,8 @@ importers: specifier: 5.1.4 version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) zod: - specifier: 4.1.11 - version: 4.1.11 + specifier: 4.1.12 + version: 4.1.12 frontend/ui: dependencies: @@ -512,7 +512,7 @@ importers: version: 6.0.0(react@19.1.1) react-i18next: specifier: 15.7.4 - version: 15.7.4(i18next@25.5.2(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) + version: 15.7.4(i18next@25.5.3(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) react-use: specifier: 17.6.0 version: 17.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -572,11 +572,11 @@ importers: specifier: 7.0.0 version: 7.0.0 semver: - specifier: 7.7.2 - version: 7.7.2 + specifier: 7.7.3 + version: 7.7.3 zod: - specifier: 4.1.11 - version: 4.1.11 + specifier: 4.1.12 + version: 4.1.12 devDependencies: '@octokit/types': specifier: 14.1.0 @@ -1825,8 +1825,8 @@ packages: prettier-plugin-ember-template-tag: optional: true - '@iconify/json@2.2.392': - resolution: {integrity: sha512-WkkQIDpmgetgvIn1jso6XKY3S5Pf9L6QD1J2RNLeiF+jzdouyayoRm2LLxe4dmnp9i3Cbf8w7oRuaVlhwK8Xtg==} + '@iconify/json@2.2.393': + resolution: {integrity: sha512-Bpf0JrndzclsNHp4TPFm8OBjUotAAxE6S6e0Af1Riu5WroiO0cbvRr2UYAqIy58YhFUJNMxgFQV3A+GHexYf6g==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -3045,8 +3045,8 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router-devtools@1.132.47': - resolution: {integrity: sha512-U6W0KB7ksnxUhuVEEhwEBFgcEuZ2VQlJp2Xf/r7x6RyzK8mG0GjJ6xAQP+rWkMzAe3zEWvaB3iXEJQOLqF+R4w==} + '@tanstack/react-router-devtools@1.132.50': + resolution: {integrity: sha512-OMtjhVvoTPliBIPLoiGdiJKgX/D5rt65xC9+yvI3Y0z6007SzDEbKLBt1Fke630bygcZlOfOjcprruqjJ1FojQ==} engines: {node: '>=12'} peerDependencies: '@tanstack/react-router': ^1.132.47 @@ -3083,12 +3083,13 @@ packages: resolution: {integrity: sha512-8YKFHmG6VUqXaWAJzEqjyW6w31dARS2USd2mtI5ZeZcihqMbskK28N4iotBXNn+sSKJnPRjc7A4jTnnEf8Mn8Q==} engines: {node: '>=12'} - '@tanstack/router-devtools-core@1.132.47': - resolution: {integrity: sha512-wdYqztGGK5X8YJWhFUTw3vCdKqNRgK6hvfcDNXbGgzVs7TgtIDnX1tfCvPDzfgORbE4CnAEUDPHVVrWcGlJGYw==} + '@tanstack/router-devtools-core@1.132.50': + resolution: {integrity: sha512-6oMevkpk06Ia3AaUHs02UQulQz8PZyYcs/U0BinVF42B8JTFlRp++HXRX4hgBnVlv81bylUnMbJ6sYASeQySUQ==} engines: {node: '>=12'} peerDependencies: '@tanstack/router-core': ^1.132.47 csstype: ^3.0.10 + solid-js: '>=1.9.5' tiny-invariant: ^1.3.3 peerDependenciesMeta: csstype: @@ -5573,8 +5574,8 @@ packages: hyphenate-style-name@1.1.0: resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} - i18next@25.5.2: - resolution: {integrity: sha512-lW8Zeh37i/o0zVr+NoCHfNnfvVw+M6FQbRp36ZZ/NyHDJ3NJVpp2HhAUyU9WafL5AssymNoOjMRB48mmx2P6Hw==} + i18next@25.5.3: + resolution: {integrity: sha512-joFqorDeQ6YpIXni944upwnuHBf5IoPMuqAchGVeQLdWC2JOjxgM9V8UGLhNIIH/Q8QleRxIi0BSRQehSrDLcg==} peerDependencies: typescript: ^5 peerDependenciesMeta: @@ -7590,6 +7591,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + serialize-error@7.0.1: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} @@ -8657,6 +8663,9 @@ packages: zod@4.1.11: resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -9774,7 +9783,7 @@ snapshots: '@commitlint/is-ignored@19.8.1': dependencies: '@commitlint/types': 19.8.1 - semver: 7.7.2 + semver: 7.7.3 '@commitlint/lint@19.8.1': dependencies: @@ -10201,7 +10210,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/json@2.2.392': + '@iconify/json@2.2.393': dependencies: '@iconify/types': 2.0.0 pathe: 2.0.3 @@ -11310,10 +11319,10 @@ snapshots: '@tanstack/query-core': 5.90.2 react: 19.1.1 - '@tanstack/react-router-devtools@1.132.47(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': + '@tanstack/react-router-devtools@1.132.50(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass-embedded@1.93.2)(sass@1.93.2)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': dependencies: '@tanstack/react-router': 1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@tanstack/router-devtools-core': 1.132.47(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) + '@tanstack/router-devtools-core': 1.132.50(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) @@ -11326,6 +11335,7 @@ snapshots: - lightningcss - sass - sass-embedded + - solid-js - stylus - sugarss - terser @@ -11373,11 +11383,12 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.132.47(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': + '@tanstack/router-devtools-core@1.132.50(@tanstack/router-core@1.132.47)(@types/node@24.5.2)(csstype@3.1.3)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': dependencies: '@tanstack/router-core': 1.132.47 clsx: 2.1.1 goober: 2.1.16(csstype@3.1.3) + solid-js: 1.9.5 tiny-invariant: 1.3.3 vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: @@ -11443,10 +11454,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.1.11)': + '@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.1.12)': dependencies: '@tanstack/react-router': 1.132.47(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - zod: 4.1.11 + zod: 4.1.12 '@tanstack/store@0.7.0': {} @@ -11928,7 +11939,7 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.3 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -11944,7 +11955,7 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.3 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -13544,7 +13555,7 @@ snapshots: eslint-compat-utils@0.5.1(eslint@9.36.0(jiti@2.6.0)): dependencies: eslint: 9.36.0(jiti@2.6.0) - semver: 7.7.2 + semver: 7.7.3 eslint-config-prettier@10.1.8(eslint@9.36.0(jiti@2.6.0)): dependencies: @@ -13615,7 +13626,7 @@ snapshots: eslint-import-context: 0.1.9(unrs-resolver@1.10.1) is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.3 stable-hash-x: 0.2.0 unrs-resolver: 1.10.1 optionalDependencies: @@ -14130,7 +14141,7 @@ snapshots: es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.7.2 + semver: 7.7.3 serialize-error: 7.0.1 optional: true @@ -14359,7 +14370,7 @@ snapshots: hyphenate-style-name@1.1.0: {} - i18next@25.5.2(typescript@5.9.2): + i18next@25.5.3(typescript@5.9.2): dependencies: '@babel/runtime': 7.28.3 optionalDependencies: @@ -14503,7 +14514,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.2 + semver: 7.7.3 is-callable@1.2.7: {} @@ -15996,11 +16007,11 @@ snapshots: dependencies: react: 19.1.1 - react-i18next@15.7.4(i18next@25.5.2(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2): + react-i18next@15.7.4(i18next@25.5.3(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2): dependencies: '@babel/runtime': 7.28.3 html-parse-stringify: 3.0.1 - i18next: 25.5.2(typescript@5.9.2) + i18next: 25.5.3(typescript@5.9.2) react: 19.1.1 optionalDependencies: react-dom: 19.1.1(react@19.1.1) @@ -16470,6 +16481,8 @@ snapshots: semver@7.7.2: {} + semver@7.7.3: {} + serialize-error@7.0.1: dependencies: type-fest: 0.13.1 @@ -16596,7 +16609,6 @@ snapshots: csstype: 3.1.3 seroval: 1.3.2 seroval-plugins: 1.3.2(seroval@1.3.2) - optional: true source-map-js@1.2.1: {} @@ -17713,4 +17725,6 @@ snapshots: zod@4.1.11: {} + zod@4.1.12: {} + zwitch@2.0.4: {} diff --git a/clash-nyanpasu/scripts/package.json b/clash-nyanpasu/scripts/package.json index ceaaf6dd71..ca7baf5fee 100644 --- a/clash-nyanpasu/scripts/package.json +++ b/clash-nyanpasu/scripts/package.json @@ -9,8 +9,8 @@ "figlet": "1.9.3", "filesize": "11.0.13", "p-retry": "7.0.0", - "semver": "7.7.2", - "zod": "4.1.11" + "semver": "7.7.3", + "zod": "4.1.12" }, "devDependencies": { "@octokit/types": "14.1.0", diff --git a/lede/package/boot/uboot-sunxi/Makefile b/lede/package/boot/uboot-sunxi/Makefile index 33fa0cbb0d..74b2927cfd 100644 --- a/lede/package/boot/uboot-sunxi/Makefile +++ b/lede/package/boot/uboot-sunxi/Makefile @@ -138,6 +138,13 @@ define U-Boot/OLIMEX_A13_SOM BUILD_DEVICES:=olimex_a13-olimex-som endef +define U-Boot/licheepi_nano + BUILD_SUBTARGET:=arm926ejs + NAME:=LicheePi Nano + UENV:=f1c + BUILD_DEVICES:=licheepi-nano +endef + define U-Boot/Linksprite_pcDuino BUILD_SUBTARGET:=cortexa8 NAME:=Linksprite pcDuino @@ -255,6 +262,13 @@ define U-Boot/pangolin UENV:=pangolin endef +define U-Boot/popstick + BUILD_SUBTARGET:=arm926ejs + NAME:=PopStick + UENV:=f1c + BUILD_DEVICES:=popstick-v1.1 +endef + define U-Boot/libretech_all_h3_cc_h5 BUILD_SUBTARGET:=cortexa53 NAME:=Libre Computer ALL-H3-CC H5 @@ -321,7 +335,6 @@ define U-Boot/sopine_baseboard ATF:=a64 endef - define U-Boot/orangepi_zero_plus BUILD_SUBTARGET:=cortexa53 NAME:=Xunlong Orange Pi Zero Plus @@ -409,6 +422,7 @@ UBOOT_TARGETS := \ Marsboard_A10 \ Mele_M9 \ OLIMEX_A13_SOM \ + licheepi_nano \ LicheePi_Zero \ Linksprite_pcDuino \ Linksprite_pcDuino3 \ @@ -435,6 +449,7 @@ UBOOT_TARGETS := \ orangepi_zero2w \ orangepi_zero3 \ pangolin \ + popstick \ pine64_plus \ Sinovoip_BPI_M3 \ sopine_baseboard \ diff --git a/lede/package/boot/uboot-sunxi/patches/260-sunxi-add-USB-support-and-PopStick-support.patch b/lede/package/boot/uboot-sunxi/patches/260-sunxi-add-USB-support-and-PopStick-support.patch new file mode 100644 index 0000000000..ecc2eb2d25 --- /dev/null +++ b/lede/package/boot/uboot-sunxi/patches/260-sunxi-add-USB-support-and-PopStick-support.patch @@ -0,0 +1,120 @@ +From 08d194d881e10e09cba7551da8079734d89ed16d Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Thu, 16 Jun 2022 00:28:41 +0800 +Subject: [PATCH 1/2] add USB support and PopStick support + +Signed-off-by: Icenowy Zheng +--- + arch/arm/dts/Makefile | 3 +- + arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 16 ++++ + arch/arm/dts/suniv-f1c100s.dtsi | 26 ++++++ + arch/arm/dts/suniv-f1c200s-popstick.dts | 89 ++++++++++++++++++++ + drivers/phy/allwinner/phy-sun4i-usb.c | 14 +++ + drivers/usb/musb-new/sunxi.c | 6 ++ + 6 files changed, 153 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/dts/suniv-f1c200s-popstick.dts + +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -647,7 +647,8 @@ dtb-$(CONFIG_STM32H7) += stm32h743i-disc + stm32h750i-art-pi.dtb + + dtb-$(CONFIG_MACH_SUNIV) += \ +- suniv-f1c100s-licheepi-nano.dtb ++ suniv-f1c100s-licheepi-nano.dtb \ ++ suniv-f1c200s-popstick.dtb + dtb-$(CONFIG_MACH_SUN4I) += \ + sun4i-a10-a1000.dtb \ + sun4i-a10-ba10-tvbox.dtb \ +--- /dev/null ++++ b/arch/arm/dts/suniv-f1c200s-popstick.dts +@@ -0,0 +1,89 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright 2022 Icenowy Zheng ++ */ ++ ++/dts-v1/; ++#include "suniv-f1c100s.dtsi" ++ ++#include ++ ++/ { ++ model = "Popcorn Computer PopStick"; ++ compatible = "sourceparts,popstick", "allwinner,suniv-f1c200s", ++ "allwinner,suniv-f1c100s"; ++ ++ aliases { ++ mmc0 = &mmc0; ++ serial0 = &uart0; ++ spi0 = &spi0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ reg_vcc3v3: vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++}; ++ ++&mmc0 { ++ broken-cd; ++ bus-width = <4>; ++ disable-wp; ++ status = "okay"; ++ vmmc-supply = <®_vcc3v3>; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pc_pins>; ++ status = "okay"; ++ ++ flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "u-boot-with-spl"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ ubi@100000 { ++ label = "ubi"; ++ reg = <0x100000 0x7f00000>; ++ }; ++ }; ++ }; ++}; ++ ++&otg_sram { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pe_pins>; ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "peripheral"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++}; diff --git a/lede/package/boot/uboot-sunxi/patches/261-sunxi-add-popstick-defconfig.patch b/lede/package/boot/uboot-sunxi/patches/261-sunxi-add-popstick-defconfig.patch new file mode 100644 index 0000000000..56f8192160 --- /dev/null +++ b/lede/package/boot/uboot-sunxi/patches/261-sunxi-add-popstick-defconfig.patch @@ -0,0 +1,51 @@ +From 0d263e1071ee3f63d2047a8bb9af4434f1cd4bb1 Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Thu, 16 Jun 2022 09:46:42 +0800 +Subject: [PATCH 2/2] HACK for UBI env and add defconfig + +--- + board/sunxi/board.c | 1 + + configs/popstick_defconfig | 37 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 38 insertions(+) + create mode 100644 configs/popstick_defconfig + +--- /dev/null ++++ b/configs/popstick_defconfig +@@ -0,0 +1,37 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT_ONLY=y ++CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y ++CONFIG_ARCH_SUNXI=y ++CONFIG_ENV_SIZE=0x1f000 ++CONFIG_DEFAULT_DEVICE_TREE="suniv-f1c200s-popstick" ++CONFIG_SPL=y ++CONFIG_MACH_SUNIV=y ++CONFIG_DRAM_CLK=156 ++CONFIG_DRAM_ZQ=0 ++# CONFIG_VIDEO_SUNXI is not set ++CONFIG_SPL_SPI_SUNXI=y ++CONFIG_SPL_SPI_SUNXI_NAND=y ++CONFIG_SPL_SPI_SUNXI_NAND_ASSUMED_PAGESIZE=0x800 ++# CONFIG_ANDROID_BOOT_IMAGE is not set ++CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000 ++CONFIG_CMD_MTD=y ++# CONFIG_CMD_SF is not set ++CONFIG_CMD_MTDPARTS=y ++CONFIG_CMD_UBI=y ++# CONFIG_ENV_IS_IN_FAT is not set ++# CONFIG_ENV_IS_IN_SPI_FLASH is not set ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="env" ++# CONFIG_NET is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++# CONFIG_SPI_FLASH is not set ++CONFIG_SF_DEFAULT_SPEED=25000000 ++# CONFIG_UBI_SILENCE_MSG is not set ++CONFIG_PHY_SUN4I_USB=y ++CONFIG_SPI=y ++CONFIG_USB_MUSB_GADGET=y ++CONFIG_USB_FUNCTION_SDP=y ++# CONFIG_UBIFS_SILENCE_MSG is not set diff --git a/lede/package/boot/uboot-sunxi/uEnv-f1c.txt b/lede/package/boot/uboot-sunxi/uEnv-f1c.txt new file mode 100644 index 0000000000..535d576d87 --- /dev/null +++ b/lede/package/boot/uboot-sunxi/uEnv-f1c.txt @@ -0,0 +1,6 @@ +setenv mmc_rootpart 2 +part uuid mmc ${mmc_bootdev}:${mmc_rootpart} uuid +setenv loadkernel fatload mmc \$mmc_bootdev \$ramdisk_addr_r uImage +setenv bootargs console=ttyS0,115200 earlyprintk root=PARTUUID=${uuid} rootwait +setenv uenvcmd run loadkernel \&\& bootm \$ramdisk_addr_r +run uenvcmd diff --git a/lede/target/linux/sunxi/Makefile b/lede/target/linux/sunxi/Makefile index d77e8ce90a..2183fa8990 100644 --- a/lede/target/linux/sunxi/Makefile +++ b/lede/target/linux/sunxi/Makefile @@ -8,7 +8,7 @@ ARCH:=arm BOARD:=sunxi BOARDNAME:=Allwinner ARM SoCs FEATURES:=ext4 display rootfs-part rtc squashfs usb usbgadget -SUBTARGETS:=cortexa8 cortexa7 cortexa53 +SUBTARGETS:=cortexa8 cortexa7 cortexa53 arm926ejs KERNEL_PATCHVER:=6.12 KERNEL_TESTING_PATCHVER:=6.6 diff --git a/lede/target/linux/sunxi/arm926ejs/config-6.12 b/lede/target/linux/sunxi/arm926ejs/config-6.12 new file mode 100644 index 0000000000..8625b9751b --- /dev/null +++ b/lede/target/linux/sunxi/arm926ejs/config-6.12 @@ -0,0 +1,56 @@ +# CONFIG_ARCH_MULTI_V4 is not set +# CONFIG_ARCH_MULTI_V4T is not set +CONFIG_ARCH_MULTI_V4_V5=y +CONFIG_ARCH_MULTI_V5=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_CPU_AUTO=y +CONFIG_ARCH_NR_GPIO=416 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_COMPAT_32BIT_TIME=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_MACH_SUNIV=y +# CONFIG_MACH_SUN4I is not set +# CONFIG_MACH_SUN5I is not set +# CONFIG_MACH_SUN6I is not set +# CONFIG_MACH_SUN7I is not set +# CONFIG_MACH_SUN8I is not set +# CONFIG_MACH_SUN9I is not set +CONFIG_MDIO_BUS_MUX=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_NOP_USB_XCEIV=y +# CONFIG_PHY_SUN9I_USB is not set +# CONFIG_PINCTRL_SUN4I_A10 is not set +# CONFIG_PINCTRL_SUN50I_A64 is not set +# CONFIG_PINCTRL_SUN50I_A64_R is not set +# CONFIG_PINCTRL_SUN50I_H5 is not set +# CONFIG_PINCTRL_SUN50I_H6 is not set +# CONFIG_PINCTRL_SUN50I_H6_R is not set +# CONFIG_PINCTRL_SUN5I is not set +# CONFIG_PINCTRL_SUN6I_A31 is not set +# CONFIG_PINCTRL_SUN6I_A31_R is not set +# CONFIG_PINCTRL_SUN8I_A23 is not set +# CONFIG_PINCTRL_SUN8I_A23_R is not set +# CONFIG_PINCTRL_SUN8I_A33 is not set +# CONFIG_PINCTRL_SUN8I_A83T is not set +# CONFIG_PINCTRL_SUN8I_A83T_R is not set +# CONFIG_PINCTRL_SUN8I_H3 is not set +# CONFIG_PINCTRL_SUN8I_H3_R is not set +# CONFIG_PINCTRL_SUN8I_V3S is not set +# CONFIG_PINCTRL_SUN9I_A80 is not set +# CONFIG_PINCTRL_SUN9I_A80_R is not set +CONFIG_PINCTRL_SUNIV_F1C100S=y +CONFIG_PINCTRL_SUNXI=y +CONFIG_SUNIV_F1C100S_CCU=y +CONFIG_UNWINDER_ARM=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_DUAL_ROLE=y +CONFIG_USB_MUSB_SUNXI=y diff --git a/lede/target/linux/sunxi/arm926ejs/target.mk b/lede/target/linux/sunxi/arm926ejs/target.mk new file mode 100644 index 0000000000..f37aa30d70 --- /dev/null +++ b/lede/target/linux/sunxi/arm926ejs/target.mk @@ -0,0 +1,11 @@ +# +# Copyright (C) 2024 Zoltan HERPAI +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +BOARDNAME:=Allwinner F1C100/200s +CPU_TYPE:=arm926ej-s diff --git a/lede/target/linux/sunxi/config-6.12 b/lede/target/linux/sunxi/config-6.12 index 5de49168b6..5c43596fba 100644 --- a/lede/target/linux/sunxi/config-6.12 +++ b/lede/target/linux/sunxi/config-6.12 @@ -7,8 +7,6 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y CONFIG_ARCH_NR_GPIO=416 CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y diff --git a/lede/target/linux/sunxi/cortexa7/config-6.12 b/lede/target/linux/sunxi/cortexa7/config-6.12 index beab75befa..e7efefa541 100644 --- a/lede/target/linux/sunxi/cortexa7/config-6.12 +++ b/lede/target/linux/sunxi/cortexa7/config-6.12 @@ -1,3 +1,5 @@ +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y CONFIG_B53=y CONFIG_B53_MDIO_DRIVER=y CONFIG_CRYPTO_BLAKE2S_ARM=y diff --git a/lede/target/linux/sunxi/cortexa8/config-6.12 b/lede/target/linux/sunxi/cortexa8/config-6.12 index b893b3142e..274778dd09 100644 --- a/lede/target/linux/sunxi/cortexa8/config-6.12 +++ b/lede/target/linux/sunxi/cortexa8/config-6.12 @@ -1,3 +1,5 @@ +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y # CONFIG_ARM_LPAE is not set CONFIG_CRYPTO_BLAKE2S_ARM=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y diff --git a/lede/target/linux/sunxi/image/arm926ejs.mk b/lede/target/linux/sunxi/image/arm926ejs.mk new file mode 100644 index 0000000000..42d3ee6f29 --- /dev/null +++ b/lede/target/linux/sunxi/image/arm926ejs.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2013-2024 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +KERNEL_LOADADDR=0x81000000 + +define Device/licheepi-nano + $(call Device/FitImageGzip) + DEVICE_VENDOR := LicheePi + DEVICE_MODEL := Nano + DEVICE_PACKAGES := kmod-rtc-sunxi + SOC := suniv-f1c100s +endef +TARGET_DEVICES += licheepi-nano + +define Device/popstick-v1.1 + $(call Device/FitImageGzip) + DEVICE_VENDOR := PopStick + DEVICE_MODEL := v1.1 + DEVICE_PACKAGES := kmod-rtc-sunxi + SOC := suniv-f1c200s +endef +TARGET_DEVICES += popstick-v1.1 diff --git a/lede/target/linux/sunxi/patches-6.12/460-f1c100s-sram-driver.patch b/lede/target/linux/sunxi/patches-6.12/460-f1c100s-sram-driver.patch new file mode 100644 index 0000000000..4bf090a080 --- /dev/null +++ b/lede/target/linux/sunxi/patches-6.12/460-f1c100s-sram-driver.patch @@ -0,0 +1,33 @@ +Allwinner ARMv5 F1C100s has similar sram controller to sun4i A10 +Add compatible strings for it. + +Signed-off-by: Mesih Kilinc +Acked-by: Maxime Ripard +--- + drivers/soc/sunxi/sunxi_sram.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -98,6 +98,10 @@ static const struct of_device_id sunxi_s + .compatible = "allwinner,sun50i-a64-sram-c", + .data = &sun50i_a64_sram_c.data, + }, ++ { ++ .compatible = "allwinner,suniv-f1c100s-sram-d", ++ .data = &sun4i_a10_sram_d.data, ++ }, + {} + }; + +@@ -430,6 +434,10 @@ static const struct of_device_id sunxi_s + .compatible = "allwinner,sun50i-h616-system-control", + .data = &sun50i_h616_sramc_variant, + }, ++ { ++ .compatible = "allwinner,suniv-f1c100s-system-control", ++ .data = &sun4i_a10_sramc_variant, ++ }, + { }, + }; + MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match); diff --git a/lede/target/linux/sunxi/patches-6.12/461-f1c100s-watchdog-compat.patch b/lede/target/linux/sunxi/patches-6.12/461-f1c100s-watchdog-compat.patch new file mode 100644 index 0000000000..8baf969a0f --- /dev/null +++ b/lede/target/linux/sunxi/patches-6.12/461-f1c100s-watchdog-compat.patch @@ -0,0 +1,18 @@ +Allwinner ARMv5 F1C100s has similar watchdog timer to sun6i A31. +Add compatible string for it. + +Signed-off-by: Mesih Kilinc +--- + drivers/watchdog/sunxi_wdt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/watchdog/sunxi_wdt.c ++++ b/drivers/watchdog/sunxi_wdt.c +@@ -240,6 +240,7 @@ static const struct of_device_id sunxi_w + { .compatible = "allwinner,sun4i-a10-wdt", .data = &sun4i_wdt_reg }, + { .compatible = "allwinner,sun6i-a31-wdt", .data = &sun6i_wdt_reg }, + { .compatible = "allwinner,sun20i-d1-wdt", .data = &sun20i_wdt_reg }, ++ { .compatible = "allwinner,suniv-f1c100s-wdt", .data = &sun6i_wdt_reg }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids); diff --git a/small/luci-app-fchomo/Makefile b/small/luci-app-fchomo/Makefile index 2de03c3cd8..e4c7350a1a 100644 --- a/small/luci-app-fchomo/Makefile +++ b/small/luci-app-fchomo/Makefile @@ -61,6 +61,9 @@ uci delete firewall.fchomo_post uci commit firewall endef +# Disable CSStidy for compilation +#CONFIG_LUCI_CSSTIDY:= + include $(TOPDIR)/feeds/luci/luci.mk # call BuildPackage - OpenWrt buildroot signature diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js index be786084a8..773b77254e 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js @@ -857,6 +857,15 @@ function removeBlankAttrs(res) { return res; } +function toUciname(str) { + if (isEmpty(str)) + return null; + + const unuciname = new RegExp(/[^a-zA-Z0-9_]+/, "g"); + + return str.replace(/[\s\.-]/g, '_').replace(unuciname, ''); +} + function getFeatures() { const callGetFeatures = rpc.declare({ object: 'luci.fchomo', @@ -1560,6 +1569,7 @@ return baseclass.extend({ yaml2json, isEmpty, removeBlankAttrs, + toUciname, getFeatures, getServiceStatus, getClashAPI, diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js index cccc952581..c906cc0550 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js @@ -11,20 +11,19 @@ 'require fchomo as hm'; -/* Thanks to luci-app-aria2 */ -const css = ' \ -#log_textarea { \ - padding: 10px; \ - text-align: left; \ -} \ -#log_textarea pre { \ - padding: .5rem; \ - word-break: break-all; \ - margin: 0; \ -} \ -.description { \ - background-color: #33ccff; \ -}'; +document.querySelector('head').appendChild(E('style', [ + '\ + #log_textarea {\ + padding: 10px;\ + text-align: left;\ + }\ + #log_textarea pre {\ + padding: .5rem;\ + word-break: break-all;\ + margin: 0;\ + }\ + ' +])); const hm_dir = '/var/run/fchomo'; @@ -107,7 +106,6 @@ function getRuntimeLog(name, option_index, section_id, in_table) { }); return E([ - E('style', [ css ]), E('div', {'class': 'cbi-map'}, [ E('h3', {'name': 'content', 'style': 'align-items: center; display: flex;'}, [ _('%s log').format(name), diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.css b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.css new file mode 100644 index 0000000000..41fbd4be93 --- /dev/null +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.css @@ -0,0 +1,68 @@ + +/* + bubbles style START +*/ +.nested-bubbles-container { + padding: 0; + + /* Visual recognition */ + /* https://github.com/openwrt/luci/blob/715f41e4c1033fc67724a32c6f1d33caba5357c6/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css#L2313 */ + color: var(--text-color-high); + text-shadow: 0 1px 1px hsla(var(--background-color-high-hsl), 0.75); +} + +/* Visual recognition */ +/* https://github.com/openwrt/luci/blob/715f41e4c1033fc67724a32c6f1d33caba5357c6/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css#L2210 */ +[data-darkmode="true"] .bubble[style] { + background: linear-gradient( + color-mix(in srgb, var(--bubble-color) 40%, var(--background-color-high)), + color-mix(in srgb, var(--bubble-color) 30%, var(--background-color-high)) + ) !important; +} + +.bubble { + /* border: 2px solid; */ + border-radius: 6px; + padding: 2px; + margin: 2px; + box-sizing: border-box; + + /* Default compact width (for desktop, will be overwritten on mobile)*/ + max-width: 100%; + width: fit-content; +} + +.bubble-label { + display: inline-block; + padding: 0 6px; + font-weight: bold; +} + +/* Desktop platform style */ +@media (min-device-width: 600px) { + .bubble { + /* Enable Flexbox to align the label and inner bubble horizontally */ + display: flex; + flex-direction: row; + align-items: center; + + /* The gap between the label and the inner bubble */ + gap: 8px; + } +} + +/* Mobile platform style */ +@media (max-device-width: 600px) { + .bubble { + /* Stack vertically, full width */ + display: block; + width: 100%; + text-align: center; + + /* The gap between the label and the inner bubble */ + margin-bottom: 8px; + } +} +/* + bubbles style END +*/ diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js index 6ec831ba9d..d2a976e03e 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js @@ -5,8 +5,90 @@ 'require view'; 'require fchomo as hm'; +'require tools.prng as random'; 'require tools.widgets as widgets'; +document.querySelector('head').appendChild(E('link', { + 'rel': 'stylesheet', + 'type': 'text/css', + 'href': L.resource('view/fchomo/node.css') +})); + +const CBIBubblesValue = form.DummyValue.extend({ + __name__: 'CBI.BubblesValue', + + load(section_id) { + const uciconfig = this.config || this.section.configthis.config || this.map.config; + const type = uci.get(uciconfig, section_id, 'type'); + const detour = uci.get(uciconfig, section_id, 'chain_tail_group') || uci.get(uciconfig, section_id, 'chain_tail'); + + switch (type) { + case 'node': + return '%s ⇒ %s'.format( + uci.get(uciconfig, section_id, 'chain_head'), + detour + ); + case 'provider': + return '%s ⇒ %s'.format( + uci.get(uciconfig, section_id, 'chain_head_sub'), + detour + ); + default: + return null; + } + }, + + textvalue(section_id) { + const cval = this.cfgvalue(section_id); + if (!cval) + return null; + + const chain = cval.split('⇒').map(t => t.trim()); + //const container_id = this.cbid(section_id) + '.bubbles'; + + let curWrapper = null; + for (let i = 0; i < chain.length; i++) { + const text = chain[i]; + + const labelEl = E('span', { + class: 'bubble-label' + }, [ text ]); + + const bubbleEl = E('div', { + class: 'bubble', + //id: container_id + `.${hm.toUciname(text)}`, + style: '--bubble-color:%s; background-color:var(--bubble-color)' + .format(random.derive_color(text)) + }, [ labelEl ]); + + if (curWrapper) + bubbleEl.insertBefore(curWrapper, bubbleEl.firstChild); + + curWrapper = bubbleEl; + } + + return E('div', { + class: 'nested-bubbles-container', + //id: container_id + }, [ curWrapper ]); + }, + + hexToRgbArray(hex) { + // Remove the '#' if it exists + const shorthandRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i; + const result = shorthandRegex.exec(hex); + + if (result) + return [ + parseInt(result[1], 16), + parseInt(result[2], 16), + parseInt(result[3], 16) + ]; + else + return null; + } +}); + function parseProviderYaml(field, name, cfg) { if (!cfg.type) return null; @@ -1449,26 +1531,7 @@ return view.extend({ so.default = 'node'; so.textvalue = hm.textvalue2Value; - so = ss.option(form.DummyValue, '_value', _('Value')); - so.load = function(section_id) { - const type = uci.get(data[0], section_id, 'type'); - const detour = uci.get(data[0], section_id, 'chain_tail_group') || uci.get(data[0], section_id, 'chain_tail'); - - switch (type) { - case 'node': - return '%s » %s'.format( - uci.get(data[0], section_id, 'chain_head'), - detour - ); - case 'provider': - return '%s » %s'.format( - uci.get(data[0], section_id, 'chain_head_sub'), - detour - ); - default: - return null; - } - } + so = ss.option(CBIBubblesValue, '_value', _('Value')); so.modalonly = false; so = ss.option(form.ListValue, 'chain_head_sub', _('Chain head') + _(' (Destination)')); diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js index e7617790cd..2b9a4e0030 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js @@ -31,10 +31,10 @@ function parseRulesetYaml(field, name, cfg) { } function parseRulesetLink(section_type, uri) { - let config, - filefmt = new RegExp(/^(text|yaml|mrs)$/), - filebehav = new RegExp(/^(domain|ipcidr|classical)$/), - unuciname = new RegExp(/[^a-zA-Z0-9_]+/, "g"); + const filefmt = new RegExp(/^(text|yaml|mrs)$/); + const filebehav = new RegExp(/^(domain|ipcidr|classical)$/); + + let config; uri = uri.split('://'); if (uri[0] && uri[1]) { @@ -46,8 +46,7 @@ function parseRulesetLink(section_type, uri) { var behavior = url.searchParams.get('behav'); var interval = url.searchParams.get('sec'); var rawquery = url.searchParams.get('rawq'); - var name = decodeURI(url.pathname).split('/').pop() - .replace(/[\s\.-]/g, '_').replace(unuciname, ''); + var name = hm.toUciname(decodeURI(url.pathname).split('/').pop()); if (filefmt.test(format) && filebehav.test(behavior)) { let fullpath = (url.username ? url.username + '@' : '') + url.host + url.pathname + (rawquery ? '?' + decodeURIComponent(rawquery) : ''); @@ -69,8 +68,7 @@ function parseRulesetLink(section_type, uri) { var behavior = url.searchParams.get('behav'); var filler = url.searchParams.get('fill'); var path = decodeURI(url.pathname); - var name = path.split('/').pop() - .replace(/[\s\.-]/g, '_').replace(unuciname, ''); + var name = hm.toUciname(path.split('/').pop()); if (filefmt.test(format) && filebehav.test(behavior)) { config = { diff --git a/small/v2raya/Makefile b/small/v2raya/Makefile index ca0578ee8c..07bb38892a 100644 --- a/small/v2raya/Makefile +++ b/small/v2raya/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=v2rayA -PKG_VERSION:=2.2.7.2 +PKG_VERSION:=2.2.7.3 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=368d57206b26ee53d59861961e7eca311f32654a4e76eab24e00d716a7ae7cd0 +PKG_HASH:=4b36275dff287d8cf03ee8fa5331d731593f35020459a8ea0ff925e8496a52cf PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service PKG_LICENSE:=AGPL-3.0-only @@ -60,7 +60,7 @@ define Download/v2raya-web URL:=https://github.com/v2rayA/v2rayA/releases/download/v$(PKG_VERSION)/ URL_FILE:=web.tar.gz FILE:=$(WEB_FILE) - HASH:=cbb9e01e80fd89f9a78459e416304160f16b764383b9cad2dcc5a6318b8543f9 + HASH:=99e789fa7cbfe9f6bc49afa8365556dff6d6c664e6136b045dd7f43322d0de7f endef define Build/Prepare diff --git a/v2raya/.github/workflows/release_main.yml b/v2raya/.github/workflows/release_main.yml index 60a994b6ff..ad2c952bdf 100644 --- a/v2raya/.github/workflows/release_main.yml +++ b/v2raya/.github/workflows/release_main.yml @@ -7,7 +7,7 @@ on: required: true jobs: Build_v2rayA_Web: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: @@ -208,7 +208,7 @@ jobs: installer_windows_inno_x64_${{ steps.prep.outputs.VERSION }}.exe installer_windows_inno_arm64_${{ steps.prep.outputs.VERSION }}.exe Build_Linux_Packages: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest needs: [Build_v2rayA_Binaries] strategy: matrix: @@ -332,7 +332,7 @@ jobs: path: | fpm_packages/* GitHub_Release: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest needs: [Build_v2rayA_Binaries, Build_Windows_Installers, Build_Linux_Packages] steps: - uses: actions/checkout@v4 @@ -394,243 +394,8 @@ jobs: -H "Authorization: Bearer $CF_PARGE_CACHE_AUTH_KEY" \ -H "Content-Type: application/json" \ --data '{"purge_everything":true}' - Build_v2ray_Debian_Packages: - runs-on: ubuntu-22.04 - steps: - - name: Install Tools - run: | - sudo apt-get update -y && sudo apt-get install -y wget curl unzip - sudo gem install fpm -v 1.15.1 - - name: Check Version - run: | - v2ray_temp_file="./v2ray.version.temp" - if ! curl -s -I "https://github.com/v2fly/v2ray-core/releases/latest" > "$v2ray_temp_file"; then - echo "${RED}Error: Cannot get latest version of v2ray!${RESET}" - exit 1 - fi - v2ray_version=$(grep -i ^location: "$v2ray_temp_file" | awk '{print $2}' | tr -d '\r' | awk -F 'tag/' '{print $2}') - rm -f "$v2ray_temp_file" - xray_temp_file="./xray.version.temp" - if ! curl -s -I "https://github.com/XTLS/Xray-core/releases/latest" > "$xray_temp_file"; then - echo "${RED}Error: Cannot get latest version of xray!${RESET}" - exit 1 - fi - xray_version=$(grep -i ^location: "$xray_temp_file" | awk '{print $2}' | tr -d '\r' | awk -F 'tag/' '{print $2}') - rm -f "$xray_temp_file" - echo "V2RAY_VERSION=$v2ray_version" >> $GITHUB_OUTPUT - echo "XRAY_VERSION=$xray_version" >> $GITHUB_OUTPUT - echo "V2RAY_VERSION=$v2ray_version" >> $GITHUB_ENV - echo "XRAY_VERSION=$xray_version" >> $GITHUB_ENV - - name: Download v2ray and Xray - run: | - mkdir xray_unzipped - mkdir v2ray_unzipped - for arch in 64 32 arm64-v8a arm32-v7a mips32 mips32le mips64 mips64le riscv64 loong64; do - wget -q https://github.com/v2fly/v2ray-core/releases/download/$V2RAY_VERSION/v2ray-linux-$arch.zip - unzip -q v2ray-linux-$arch.zip -d v2ray_unzipped/v2ray-linux-$arch - wget -q https://github.com/XTLS/xray-core/releases/download/$XRAY_VERSION/Xray-linux-$arch.zip - unzip -q Xray-linux-$arch.zip -d xray_unzipped/xray-linux-$arch - done - - name: Build v2ray Packages - run: | - mkdir v2ray_packages - package_version="$(echo "$V2RAY_VERSION" | sed 's/v//g')" # Remove the leading 'v' in version number - for arch in amd64 i386 arm64 armhf mips mips32le mips64 mips64le riscv64 loong64; do - case $arch in - amd64) - source_dir="v2ray_unzipped/v2ray-linux-64" - ;; - i386) - source_dir="v2ray_unzipped/v2ray-linux-32" - ;; - arm64) - source_dir="v2ray_unzipped/v2ray-linux-arm64-v8a" - ;; - armhf) - source_dir="v2ray_unzipped/v2ray-linux-arm32-v7a" - ;; - mips) - source_dir="v2ray_unzipped/v2ray-linux-mips32" - ;; - mips32le) - source_dir="v2ray_unzipped/v2ray-linux-mips32le" - ;; - mips64) - source_dir="v2ray_unzipped/v2ray-linux-mips64" - ;; - mips64le) - source_dir="v2ray_unzipped/v2ray-linux-mips64le" - ;; - riscv64) - source_dir="v2ray_unzipped/v2ray-linux-riscv64" - ;; - loong64) - source_dir="v2ray_unzipped/v2ray-linux-loong64" - ;; - esac - echo 'systemctl daemon-reload - if [ "$(systemctl is-active v2ray)" = "active" ]; then - systemctl restart v2ray - fi' > $source_dir/postinst - echo "systemctl daemon-reload" >> $source_dir/post-remove - sed -i 's|usr/local/bin/v2ray|usr/bin/v2ray|g' $source_dir/systemd/system/v2ray.service - sed -i 's|usr/local/bin/v2ray|usr/bin/v2ray|g' $source_dir/systemd/system/v2ray@.service - sed -i 's|usr/local/etc/v2ray|etc/v2ray|g' $source_dir/systemd/system/v2ray.service - sed -i 's|usr/local/etc/v2ray|etc/v2ray|g' $source_dir/systemd/system/v2ray@.service - fpm -s dir -t deb -a $arch --version $package_version \ - --url 'https://v2fly.org/' --description 'A platform for building proxies to bypass network restrictions' \ - --maintainer "v2raya@v2raya.org" --name v2ray --license 'MIT' \ - --package ./v2ray_packages/v2ray_"$arch"_"$package_version".deb \ - --after-install $source_dir/postinst \ - --after-remove $source_dir/post-remove \ - $source_dir/v2ray=/usr/bin/v2ray \ - $source_dir/systemd/system/v2ray.service=/usr/lib/systemd/system/v2ray.service \ - $source_dir/systemd/system/v2ray@.service=/usr/lib/systemd/system/v2ray@.service \ - $source_dir/geoip.dat=/usr/share/v2ray/geoip.dat \ - $source_dir/geoip-only-cn-private.dat=/usr/share/v2ray/geoip-only-cn-private.dat \ - $source_dir/geosite.dat=/usr/share/v2ray/geosite.dat - done - - name: Build Xray Packages - run: | - mkdir xray_packages - package_version="$(echo "$XRAY_VERSION" | sed 's/v//g')" # Remove the leading 'v' in version number - for arch in amd64 i386 arm64 armhf mips mips32le mips64 mips64le riscv64 loong64; do - case $arch in - amd64) - source_dir="xray_unzipped/xray-linux-64" - ;; - i386) - source_dir="xray_unzipped/xray-linux-32" - ;; - arm64) - source_dir="xray_unzipped/xray-linux-arm64-v8a" - ;; - armhf) - source_dir="xray_unzipped/xray-linux-arm32-v7a" - ;; - mips) - source_dir="xray_unzipped/xray-linux-mips32" - ;; - mips32le) - source_dir="xray_unzipped/xray-linux-mips32le" - ;; - mips64) - source_dir="xray_unzipped/xray-linux-mips64" - ;; - mips64le) - source_dir="xray_unzipped/xray-linux-mips64le" - ;; - riscv64) - source_dir="xray_unzipped/xray-linux-riscv64" - ;; - loong64) - source_dir="xray_unzipped/xray-linux-loong64" - ;; - esac - fpm -s dir -t deb -a $arch --version $package_version \ - --url 'https://xtls.github.io/' --description 'Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration' \ - --maintainer "v2raya@v2raya.org" --name xray --license 'MPL-2.0' \ - --package ./xray_packages/xray_"$arch"_"$package_version".deb \ - $source_dir/xray=/usr/bin/xray \ - $source_dir/geoip.dat=/usr/share/xray/geoip.dat \ - $source_dir/geosite.dat=/usr/share/xray/geosite.dat - done - - name: Note Version Number - run: | - echo "V2RAY_VERSION=$V2RAY_VERSION" >> ./v2ray_packages_version.txt - echo "XRAY_VERSION=$XRAY_VERSION" >> ./xray_packages_version.txt - - name: Upload Artifact - uses: nanoufo/action-upload-artifacts-and-release-assets@v2 - with: - path: | - v2ray_packages/* - xray_packages/* - v2ray_packages_version.txt - xray_packages_version.txt - Build_APT_Repository_and_AUR: - runs-on: ubuntu-22.04 - needs: [Build_v2rayA_Binaries, Build_Linux_Packages, Build_v2ray_Debian_Packages] - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Check Version - id: prep - env: - REF: ${{ inputs.tag }} - run: | - echo "P_DIR=$(pwd)" >> $GITHUB_OUTPUT - tag=${{ inputs.tag }} - version=$(echo $tag | sed 's/v//g') - echo "VERSION=$version" >> $GITHUB_OUTPUT - echo "VERSION=$version" >> $GITHUB_ENV - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: builds/ - - name: Prepare Builds - run: | - sudo apt install -y lintian reprepro gnupg gnupg2 expect >> /dev/null - mv builds/web.tar.gz/web.tar.gz ./web.tar.gz - v2ray_version="$(cat builds/v2ray_packages_version.txt/v2ray_packages_version.txt | awk -F 'v' '{print $2}')" - echo "v2ray core version: $v2ray_version" - xray_version="$(cat builds/xray_packages_version.txt/xray_packages_version.txt | awk -F 'v' '{print $2}')" - echo "xray core version: $xray_version" - for deb_File in $(ls builds | grep -E "^v2ray_"); do - mv builds/$deb_File/$deb_File ./$deb_File - done - for deb_File in $(ls builds | grep -E "^xray_"); do - mv builds/$deb_File/$deb_File ./$deb_File - done - for deb_File in $(ls builds | grep -E "^installer_"); do - mv builds/$deb_File/$deb_File ./$deb_File - done - for v2raya_bin in $(ls builds | grep -E "^v2raya_linux"); do - mv builds/"$v2raya_bin"/"$v2raya_bin" ./"$v2raya_bin" - done - ls -lh ./ - echo "V2RAY_VERSION=$v2ray_version" >> $GITHUB_OUTPUT - echo "XRAY_VERSION=$xray_version" >> $GITHUB_OUTPUT - echo "V2RAY_VERSION=$v2ray_version" >> $GITHUB_ENV - echo "XRAY_VERSION=$xray_version" >> $GITHUB_ENV - - name: Import GPG key - id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5.4.0 - with: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.SIGNING_PASSWORD }} - - name: Generate APT Repository - env: - SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} - run: | - mkdir -p apt/incoming && cp -r install/debian/key install/debian/conf apt/ - install/tool/reprepro_expect --ask-passphrase -Vb apt includedeb v2raya installer_debian_*_$VERSION.deb xray_*_$XRAY_VERSION.deb v2ray_*_$V2RAY_VERSION.deb - install/tool/reprepro_expect --ask-passphrase -Vb apt export - mkdir apt/static/ - cp v2raya_*_*_${{ steps.prep.outputs.VERSION }}* apt/static/ - cp web.tar.gz apt/static/web_$VERSION.tar.gz - echo "apt.v2raya.org" > apt/CNAME - - name: Deploy APT Repository - uses: crazy-max/ghaction-github-pages@v3.2.0 - with: - repo: v2rayA/v2raya-apt - target_branch: master - build_dir: apt - env: - GH_PAT: ${{ secrets.PERSONAL_ACCESS_TOKEN }} - - name: AUR Release - env: - P_DIR: ${{ steps.prep.outputs.P_DIR }} - SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} - run: | - eval $(ssh-agent) - echo "$SSH_PRIVATE_KEY" > ./key - chmod 0600 ./key - ./install/tool/ssh-add_expect ./key - bash install/aur/deploy.sh Release_to_Homebrew: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest needs: [Build_v2rayA_Binaries] steps: - uses: actions/checkout@v4 @@ -684,7 +449,7 @@ jobs: v2raya-x86_64-macos.zip v2raya-x86_64-macos.zip.sha256.txt \ v2raya-aarch64-macos.zip v2raya-aarch64-macos.zip.sha256.txt Release_v2rayA_to_Docker: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest needs: [GitHub_Release] steps: - uses: actions/checkout@v4 @@ -735,7 +500,7 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max Release_v2rayA_GUI_to_Docker: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest needs: [Build_v2rayA_Web] steps: - uses: actions/checkout@v4 @@ -810,3 +575,43 @@ jobs: $Installer_x64_url = "https://github.com/v2rayA/v2rayA/releases/download/v${{ steps.prep.outputs.VERSION }}/installer_windows_inno_x64_${{ steps.prep.outputs.VERSION }}.exe" $Installer_ARM64_url = "https://github.com/v2rayA/v2rayA/releases/download/v${{ steps.prep.outputs.VERSION }}/installer_windows_inno_arm64_${{ steps.prep.outputs.VERSION }}.exe" ./wingetcreate.exe update v2rayA.v2rayA --urls $Installer_x64_url $Installer_ARM64_url --version ${{ steps.prep.outputs.VERSION }} --token ${{ secrets.HOMEBREW_V2RAYA_TOKEN }} --submit + Release_to_AUR: + runs-on: ubuntu-latest + needs: [GitHub_Release] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Check Version + id: prep + shell: bash + env: + REF: ${{ inputs.tag }} + run: | + tag=${{ inputs.tag }} + version=$(echo $tag | sed 's/v//g') + echo "VERSION=$version" >> $GITHUB_OUTPUT + echo "VERSION=$version" >> $GITHUB_ENV + - name: Download v2rayA binary for checksum + run: | + mkdir v2raya_linux + for arch in x86 x64 longarch64 armv7 arm64; do + curl -L https://github.com/v2rayA/v2rayA/releases/download/v${VERSION}/v2raya_linux_${arch}_${VERSION} -o v2raya_linux/v2raya_linux_${arch}_${VERSION} + chmod +x v2raya_linux/v2raya_linux_${arch}_${VERSION} + done + - name: Set Path + run: | + ls -l v2raya_linux + echo "P_DIR=$(pwd)/v2raya_linux" >> $GITHUB_ENV + echo "P_DIR=$(pwd)/v2raya_linux" >> $GITHUB_OUTPUT + id: set_path + - name: Release to AUR + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + run: | + eval $(ssh-agent) + echo "$SSH_PRIVATE_KEY" > ./key + chmod 0600 ./key + ./install/tool/ssh-add_expect ./key + bash install/aur/deploy.sh \ No newline at end of file diff --git a/v2raya/install/aur/v2raya-bin/.SRCINFO b/v2raya/install/aur/v2raya-bin/.SRCINFO index 18f8de2b8e..0a59828c87 100644 --- a/v2raya/install/aur/v2raya-bin/.SRCINFO +++ b/v2raya/install/aur/v2raya-bin/.SRCINFO @@ -21,15 +21,15 @@ pkgbase = v2raya-bin sha1sums = {{sha_service_lite}} sha1sums = {{sha_png}} sha1sums = {{sha_desktop}} - source_i686 = v2raya_{{pkgver}}::https://apt.v2raya.org/static/v2raya_linux_x86_{{pkgver}} + source_i686 = v2raya_{{pkgver}}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_x86_${pkgver} sha1sums_i686 = {{sha1sums_i686}} - source_x86_64 = v2raya_{{pkgver}}::https://apt.v2raya.org/static/v2raya_linux_x64_{{pkgver}} + source_x86_64 = v2raya_{{pkgver}}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_x64_${pkgver} sha1sums_x86_64 = {{sha1sums_x86_64}} - source_armv7h = v2raya_{{pkgver}}::https://apt.v2raya.org/static/v2raya_linux_armv7_{{pkgver}} + source_armv7h = v2raya_{{pkgver}}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_armv7_${pkgver} sha1sums_armv7h = {{sha1sums_armv7h}} - source_loong64 = v2raya_{{pkgver}}::https://apt.v2raya.org/static/v2raya_linux_loongarch64_{{pkgver}} + source_loong64 = v2raya_{{pkgver}}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_loongarch64_${pkgver} sha1sums_loong64 = {{sha1sums_loong64}} - source_aarch64 = v2raya_{{pkgver}}::https://apt.v2raya.org/static/v2raya_linux_arm64_{{pkgver}} + source_aarch64 = v2raya_{{pkgver}}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_arm64_${pkgver} sha1sums_aarch64 = {{sha1sums_aarch64}} pkgname = v2raya-bin diff --git a/v2raya/install/aur/v2raya-bin/PKGBUILD b/v2raya/install/aur/v2raya-bin/PKGBUILD index 944603bda1..482b2e1ed3 100644 --- a/v2raya/install/aur/v2raya-bin/PKGBUILD +++ b/v2raya/install/aur/v2raya-bin/PKGBUILD @@ -26,19 +26,19 @@ source=( ) source_i686=( - "v2raya_${pkgver}::https://apt.v2raya.org/static/v2raya_linux_x86_${pkgver}" + "v2raya_${pkgver}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_x86_${pkgver}" ) source_x86_64=( - "v2raya_${pkgver}::https://apt.v2raya.org/static/v2raya_linux_x64_${pkgver}" + "v2raya_${pkgver}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_x64_${pkgver}" ) source_aarch64=( - "v2raya_${pkgver}::https://apt.v2raya.org/static/v2raya_linux_arm64_${pkgver}" + "v2raya_${pkgver}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_arm64_${pkgver}" ) source_armv7h=( - "v2raya_${pkgver}::https://apt.v2raya.org/static/v2raya_linux_armv7_${pkgver}" + "v2raya_${pkgver}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_armv7_${pkgver}" ) source_loong64=( - "v2raya_${pkgver}::https://apt.v2raya.org/static/v2raya_linux_loongarch64_${pkgver}" + "v2raya_${pkgver}::https://github.com/v2rayA/v2rayA/releases/download/v${pkgver}/v2raya_linux_loongarch64_${pkgver}" ) sha1sums=( diff --git a/v2rayn/v2rayN/ServiceLib/Common/Extension.cs b/v2rayn/v2rayN/ServiceLib/Common/Extension.cs index 49d59534cd..d36b8169e1 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/Extension.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/Extension.cs @@ -84,4 +84,14 @@ public static class Extension { return source.Concat(new[] { string.Empty }).ToList(); } + + public static bool IsGroupType(this EConfigType configType) + { + return configType is EConfigType.PolicyGroup or EConfigType.ProxyChain; + } + + public static bool IsComplexType(this EConfigType configType) + { + return configType is EConfigType.Custom or EConfigType.PolicyGroup or EConfigType.ProxyChain; + } } diff --git a/v2rayn/v2rayN/ServiceLib/Enums/EConfigType.cs b/v2rayn/v2rayN/ServiceLib/Enums/EConfigType.cs index 5ddb8451b9..287d7b94b1 100644 --- a/v2rayn/v2rayN/ServiceLib/Enums/EConfigType.cs +++ b/v2rayn/v2rayN/ServiceLib/Enums/EConfigType.cs @@ -13,8 +13,6 @@ public enum EConfigType WireGuard = 9, HTTP = 10, Anytls = 11, - - Group = 1000, - PolicyGroup = 1001, - ProxyChain = 1002, + PolicyGroup = 101, + ProxyChain = 102, } diff --git a/v2rayn/v2rayN/ServiceLib/Enums/ERuleType.cs b/v2rayn/v2rayN/ServiceLib/Enums/ERuleType.cs new file mode 100644 index 0000000000..7455bf2a7b --- /dev/null +++ b/v2rayn/v2rayN/ServiceLib/Enums/ERuleType.cs @@ -0,0 +1,8 @@ +namespace ServiceLib.Enums; + +public enum ERuleType +{ + ALL = 0, + Routing = 1, + DNS = 2, +} diff --git a/v2rayn/v2rayN/ServiceLib/Global.cs b/v2rayn/v2rayN/ServiceLib/Global.cs index c7f18d2c55..16741fc13e 100644 --- a/v2rayn/v2rayN/ServiceLib/Global.cs +++ b/v2rayn/v2rayN/ServiceLib/Global.cs @@ -316,6 +316,8 @@ public class Global EConfigType.HTTP, ]; + public static readonly HashSet SingboxOnlyConfigType = SingboxSupportConfigType.Except(XraySupportConfigType).ToHashSet(); + public static readonly List DomainStrategies = [ AsIs, diff --git a/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 33a5c52ae6..787d64f315 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -357,7 +357,7 @@ public static class ConfigHandler { } } - else if (profileItem.ConfigType > EConfigType.Group) + else if (profileItem.ConfigType.IsGroupType()) { var profileGroupItem = await AppManager.Instance.GetProfileGroupItem(it.IndexId); await AddGroupServerCommon(config, profileItem, profileGroupItem, true); @@ -1255,7 +1255,7 @@ public static class ConfigHandler if (node.ConfigType != EConfigType.Custom && coreType != ECoreType.sing_box && config.TunModeItem.EnableTun) { var tun2SocksAddress = node.Address; - if (node.ConfigType > EConfigType.Group) + if (node.ConfigType.IsGroupType()) { var lstAddresses = (await ProfileGroupItemManager.GetAllChildDomainAddresses(node.IndexId)).ToList(); if (lstAddresses.Count > 0) diff --git a/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs index 69c0b915f3..15c14d079f 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs @@ -54,7 +54,7 @@ public class ActionPrecheckManager(Config config) private async Task> ValidateNodeAndCoreSupport(ProfileItem item, ECoreType? coreType = null) { var errors = new List(); - + coreType ??= AppManager.Instance.GetCoreType(item, item.ConfigType); if (item.ConfigType is EConfigType.Custom) @@ -77,7 +77,6 @@ public class ActionPrecheckManager(Config config) return errors; } - switch (item.ConfigType) { case EConfigType.VMess: @@ -113,7 +112,7 @@ public class ActionPrecheckManager(Config config) } } - if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (item.ConfigType.IsGroupType()) { ProfileGroupItemManager.Instance.TryGet(item.IndexId, out var group); if (group is null || group.ChildItems.IsNullOrEmpty()) @@ -136,7 +135,7 @@ public class ActionPrecheckManager(Config config) { continue; } - + var childItem = await AppManager.Instance.GetProfileItem(child); if (childItem is null) { diff --git a/v2rayn/v2rayN/ServiceLib/Manager/CoreManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/CoreManager.cs index 07876db8b3..bd01fe5b88 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/CoreManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/CoreManager.cs @@ -95,7 +95,7 @@ public class CoreManager public async Task LoadCoreConfigSpeedtest(List selecteds) { - var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls) ? ECoreType.sing_box : ECoreType.Xray; + var coreType = selecteds.Any(t => Global.SingboxOnlyConfigType.Contains(t.ConfigType)) ? ECoreType.sing_box : ECoreType.Xray; var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false)); var configPath = Utils.GetBinConfigPath(fileName); var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType); diff --git a/v2rayn/v2rayN/ServiceLib/Manager/ProfileGroupItemManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/ProfileGroupItemManager.cs index 09e6461fbd..72c55870cb 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/ProfileGroupItemManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/ProfileGroupItemManager.cs @@ -269,7 +269,7 @@ public class ProfileGroupItemManager { childAddresses.Add(childNode.Address); } - else if (childNode.ConfigType > EConfigType.Group) + else if (childNode.ConfigType.IsGroupType()) { var subAddresses = await GetAllChildDomainAddresses(childNode.IndexId); foreach (var addr in subAddresses) diff --git a/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs b/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs index da34600bd0..55f658e9b2 100644 --- a/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs +++ b/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs @@ -66,7 +66,7 @@ public class ProfileItem : ReactiveObject public bool IsComplex() { - return ConfigType is EConfigType.Custom or > EConfigType.Group; + return ConfigType.IsComplexType(); } public bool IsValid() diff --git a/v2rayn/v2rayN/ServiceLib/Models/RulesItem.cs b/v2rayn/v2rayN/ServiceLib/Models/RulesItem.cs index 2aedae0806..5a5cf52956 100644 --- a/v2rayn/v2rayN/ServiceLib/Models/RulesItem.cs +++ b/v2rayn/v2rayN/ServiceLib/Models/RulesItem.cs @@ -15,4 +15,5 @@ public class RulesItem public List? Process { get; set; } public bool Enabled { get; set; } = true; public string? Remarks { get; set; } + public ERuleType? RuleType { get; set; } } diff --git a/v2rayn/v2rayN/ServiceLib/Models/RulesItemModel.cs b/v2rayn/v2rayN/ServiceLib/Models/RulesItemModel.cs index 973f2b84cb..f3eda16bd1 100644 --- a/v2rayn/v2rayN/ServiceLib/Models/RulesItemModel.cs +++ b/v2rayn/v2rayN/ServiceLib/Models/RulesItemModel.cs @@ -7,4 +7,5 @@ public class RulesItemModel : RulesItem public string Ips { get; set; } public string Domains { get; set; } public string Protocols { get; set; } + public string RuleTypeName { get; set; } } diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 6b4257a1e6..fa04e98c5a 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3156,6 +3156,24 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Rule Type 的本地化字符串。 + /// + public static string TbRuleType { + get { + return ResourceManager.GetString("TbRuleType", resourceCulture); + } + } + + /// + /// 查找类似 You can set separate rules for Routing and DNS, or select "ALL" to apply to both 的本地化字符串。 + /// + public static string TbRuleTypeTips { + get { + return ResourceManager.GetString("TbRuleTypeTips", resourceCulture); + } + } + /// /// 查找类似 Bootstrap DNS (sing-box) 的本地化字符串。 /// diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index ae08f28d5f..9fda034c7d 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1596,4 +1596,10 @@ If the system does not have a tray function, please do not enable it + + Rule Type + + + You can set separate rules for Routing and DNS, or select "ALL" to apply to both + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 00fbced763..49e7e8c4b3 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1596,4 +1596,10 @@ If the system does not have a tray function, please do not enable it + + You can set separate rules for Routing and DNS, or select "ALL" to apply to both + + + Rule Type + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx index 5b08c3345e..4836f00556 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1596,4 +1596,10 @@ If the system does not have a tray function, please do not enable it + + You can set separate rules for Routing and DNS, or select "ALL" to apply to both + + + Rule Type + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx index e82d874f28..5fd8640fa4 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1596,4 +1596,10 @@ If the system does not have a tray function, please do not enable it + + You can set separate rules for Routing and DNS, or select "ALL" to apply to both + + + Rule Type + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 404354efd6..eaf55173bb 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1593,4 +1593,10 @@ 如果系统没有托盘功能,请不要开启 + + 规则类型 + + + 可对 Routing 和 DNS 单独设定规则,ALL 则都生效 + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index f3fd34c570..0ee39e315f 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1593,4 +1593,10 @@ 如果系統沒有托盤功能,請不要開啟 + + 规则类型 + + + 可对 Routing 和 DNS 单独设定规则,ALL 则都生效 + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs index fd77480a4a..e7644a3d1d 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs @@ -1,5 +1,6 @@ using System.Net; using System.Net.NetworkInformation; +using ServiceLib.Common; namespace ServiceLib.Services.CoreConfig; @@ -28,13 +29,14 @@ public partial class CoreConfigSingboxService(Config config) } ret.Msg = ResUI.InitialConfiguration; - - if (node?.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + + if (node.ConfigType.IsGroupType()) { switch (node.ConfigType) { case EConfigType.PolicyGroup: return await GenerateClientMultipleLoadConfig(node); + case EConfigType.ProxyChain: return await GenerateClientChainConfig(node); } diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs index 10c82eedda..ba5560f0fb 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs @@ -253,6 +253,11 @@ public partial class CoreConfigSingboxService continue; } + if (item.RuleType == ERuleType.Routing) + { + continue; + } + var rule = new Rule4Sbox(); var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule)); if (validDomains <= 0) diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index 46c90b23c0..097df4c3c5 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -208,7 +208,7 @@ public partial class CoreConfigSingboxService { try { - if (node.ConfigType is not (EConfigType.PolicyGroup or EConfigType.ProxyChain)) + if (!node.ConfigType.IsGroupType()) { return -1; } @@ -236,9 +236,11 @@ public partial class CoreConfigSingboxService } break; + case EConfigType.ProxyChain: await GenChainOutboundsList(childProfiles, singboxConfig, baseTagName); break; + default: break; } @@ -492,7 +494,7 @@ public partial class CoreConfigSingboxService { index++; - if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId); if (childProfiles.Count <= 0) @@ -667,7 +669,7 @@ public partial class CoreConfigSingboxService var node = nodes[i]; if (node == null) continue; - if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId); if (childProfiles.Count <= 0) diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs index 3994e21bf6..4855c7d6cc 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs @@ -136,13 +136,21 @@ public partial class CoreConfigSingboxService var rules = JsonUtils.Deserialize>(routing.RuleSet); foreach (var item1 in rules ?? []) { - if (item1.Enabled) + if (!item1.Enabled) { - await GenRoutingUserRule(item1, singboxConfig); - if (item1.Ip != null && item1.Ip.Count > 0) - { - ipRules.Add(item1); - } + continue; + } + + if (item1.RuleType == ERuleType.DNS) + { + continue; + } + + await GenRoutingUserRule(item1, singboxConfig); + + if (item1.Ip?.Count > 0) + { + ipRules.Add(item1); } } } @@ -371,7 +379,7 @@ public partial class CoreConfigSingboxService if (node == null || (!Global.SingboxSupportConfigType.Contains(node.ConfigType) - && node.ConfigType is not (EConfigType.PolicyGroup or EConfigType.ProxyChain))) + && !node.ConfigType.IsGroupType())) { return Global.ProxyTag; } @@ -383,7 +391,7 @@ public partial class CoreConfigSingboxService return tag; } - if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { var ret = await GenGroupOutbound(node, singboxConfig, tag); if (ret == 0) diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs index 37c55bca75..8c31ddae30 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs @@ -30,12 +30,13 @@ public partial class CoreConfigV2rayService(Config config) ret.Msg = ResUI.InitialConfiguration; - if (node?.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { switch (node.ConfigType) { case EConfigType.PolicyGroup: return await GenerateClientMultipleLoadConfig(node); + case EConfigType.ProxyChain: return await GenerateClientChainConfig(node); } diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs index 744286d4fa..5952513520 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayDnsService.cs @@ -142,6 +142,11 @@ public partial class CoreConfigV2rayService continue; } + if (item.RuleType == ERuleType.Routing) + { + continue; + } + foreach (var domain in item.Domain) { if (domain.StartsWith('#')) diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs index 58e4a840e9..ef642ce512 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs @@ -484,7 +484,7 @@ public partial class CoreConfigV2rayService { try { - if (node.ConfigType is not (EConfigType.PolicyGroup or EConfigType.ProxyChain)) + if (!node.ConfigType.IsGroupType()) { return -1; } @@ -511,9 +511,11 @@ public partial class CoreConfigV2rayService await GenOutboundsListWithChain(childProfiles, v2rayConfig, baseTagName); } break; + case EConfigType.ProxyChain: await GenChainOutboundsList(childProfiles, v2rayConfig, baseTagName); break; + default: break; } @@ -629,7 +631,7 @@ public partial class CoreConfigV2rayService { index++; - if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId); if (childProfiles.Count <= 0) @@ -780,7 +782,7 @@ public partial class CoreConfigV2rayService var node = nodes[i]; if (node == null) continue; - if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId); if (childProfiles.Count <= 0) diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs index e4a6741003..83df2ab217 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayRoutingService.cs @@ -20,11 +20,18 @@ public partial class CoreConfigV2rayService var rules = JsonUtils.Deserialize>(routing.RuleSet); foreach (var item in rules) { - if (item.Enabled) + if (!item.Enabled) { - var item2 = JsonUtils.Deserialize(JsonUtils.Serialize(item)); - await GenRoutingUserRule(item2, v2rayConfig); + continue; } + + if (item.RuleType == ERuleType.DNS) + { + continue; + } + + var item2 = JsonUtils.Deserialize(JsonUtils.Serialize(item)); + await GenRoutingUserRule(item2, v2rayConfig); } } } @@ -128,7 +135,7 @@ public partial class CoreConfigV2rayService if (node == null || (!Global.XraySupportConfigType.Contains(node.ConfigType) - && node.ConfigType is not (EConfigType.PolicyGroup or EConfigType.ProxyChain))) + && !node.ConfigType.IsGroupType())) { return Global.ProxyTag; } @@ -139,7 +146,7 @@ public partial class CoreConfigV2rayService return tag; } - if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + if (node.ConfigType.IsGroupType()) { var ret = await GenGroupOutbound(node, v2rayConfig, tag); if (ret == 0) diff --git a/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs index 1fff0dbed5..b2cd6a2b58 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs @@ -64,7 +64,7 @@ public class SpeedtestService(Config config, Func updateF var lstSelected = new List(); foreach (var it in selecteds) { - if (it.ConfigType == EConfigType.Custom) + if (it.ConfigType.IsComplexType()) { continue; } @@ -116,10 +116,6 @@ public class SpeedtestService(Config config, Func updateF List tasks = []; foreach (var it in selecteds) { - if (it.ConfigType == EConfigType.Custom) - { - continue; - } tasks.Add(Task.Run(async () => { try @@ -199,10 +195,6 @@ public class SpeedtestService(Config config, Func updateF { continue; } - if (it.ConfigType == EConfigType.Custom) - { - continue; - } tasks.Add(Task.Run(async () => { await DoRealPing(it); @@ -216,7 +208,10 @@ public class SpeedtestService(Config config, Func updateF } finally { - await processService?.StopAsync(); + if (processService != null) + { + await processService?.StopAsync(); + } } return true; } @@ -233,10 +228,6 @@ public class SpeedtestService(Config config, Func updateF await UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); continue; } - if (it.ConfigType == EConfigType.Custom) - { - continue; - } await concurrencySemaphore.WaitAsync(); tasks.Add(Task.Run(async () => @@ -272,7 +263,10 @@ public class SpeedtestService(Config config, Func updateF } finally { - await processService?.StopAsync(); + if (processService != null) + { + await processService?.StopAsync(); + } concurrencySemaphore.Release(); } })); @@ -345,7 +339,7 @@ public class SpeedtestService(Config config, Func updateF { List> lstTest = new(); var lst1 = lstSelected.Where(t => Global.XraySupportConfigType.Contains(t.ConfigType)).ToList(); - var lst2 = lstSelected.Where(t => Global.SingboxSupportConfigType.Contains(t.ConfigType) && !Global.XraySupportConfigType.Contains(t.ConfigType)).ToList(); + var lst2 = lstSelected.Where(t => Global.SingboxOnlyConfigType.Contains(t.ConfigType)).ToList(); for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++) { diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index a0803309c3..8120b64d2f 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -350,7 +350,7 @@ public class MainWindowViewModel : MyReactiveObject { ret = await _updateView?.Invoke(EViewAction.AddServer2Window, item); } - else if (eConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + else if (eConfigType.IsGroupType()) { ret = await _updateView?.Invoke(EViewAction.AddGroupServerWindow, item); } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index 289dc36e51..8223632d51 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -510,7 +510,7 @@ public class ProfilesViewModel : MyReactiveObject { ret = await _updateView?.Invoke(EViewAction.AddServer2Window, item); } - else if (eConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) + else if (eConfigType.IsGroupType()) { ret = await _updateView?.Invoke(EViewAction.AddGroupServerWindow, item); } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs index 758aa8fe55..36b1babf1a 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs @@ -21,6 +21,9 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject [Reactive] public string Process { get; set; } + [Reactive] + public string? RuleType { get; set; } + [Reactive] public bool AutoSort { get; set; } @@ -51,6 +54,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject Domain = Utils.List2String(SelectedSource.Domain, true); IP = Utils.List2String(SelectedSource.Ip, true); Process = Utils.List2String(SelectedSource.Process, true); + RuleType = SelectedSource.RuleType?.ToString(); } private async Task SaveRulesAsync() @@ -73,6 +77,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject } SelectedSource.Protocol = ProtocolItems?.ToList(); SelectedSource.InboundTag = InboundTagItems?.ToList(); + SelectedSource.RuleType = RuleType.IsNullOrEmpty() ? null : (ERuleType)Enum.Parse(typeof(ERuleType), RuleType); var hasRule = SelectedSource.Domain?.Count > 0 || SelectedSource.Ip?.Count > 0 diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs index 4b192f04a8..979d3dc495 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs @@ -107,13 +107,13 @@ public class RoutingRuleSettingViewModel : MyReactiveObject var it = new RulesItemModel() { Id = item.Id, + RuleTypeName = item.RuleType?.ToString(), OutboundTag = item.OutboundTag, Port = item.Port, Network = item.Network, Protocols = Utils.List2String(item.Protocol), InboundTags = Utils.List2String(item.InboundTag), - Domains = Utils.List2String(item.Domain), - Ips = Utils.List2String(item.Ip), + Domains = Utils.List2String((item.Domain ?? []).Concat(item.Ip ?? []).ToList()), Enabled = item.Enabled, Remarks = item.Remarks, }; diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs index 720e5c2984..2acaee559f 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs @@ -40,6 +40,7 @@ public partial class AddGroupServerWindow : WindowBase case EConfigType.PolicyGroup: this.Title = ResUI.TbConfigTypePolicyGroup; break; + case EConfigType.ProxyChain: this.Title = ResUI.TbConfigTypeProxyChain; gridPolicyGroup.IsVisible = false; @@ -115,18 +116,22 @@ public partial class AddGroupServerWindow : WindowBase ViewModel?.MoveServer(EMove.Top); e.Handled = true; break; + case Key.U: ViewModel?.MoveServer(EMove.Up); e.Handled = true; break; + case Key.D: ViewModel?.MoveServer(EMove.Down); e.Handled = true; break; + case Key.B: ViewModel?.MoveServer(EMove.Bottom); e.Handled = true; break; + case Key.Delete: ViewModel?.ChildRemoveAsync(); e.Handled = true; @@ -162,5 +167,4 @@ public partial class AddGroupServerWindow : WindowBase ViewModel.SelectedChildren = lstChild.SelectedItems.Cast().ToList(); } } - } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index 35366e5724..0fa30a521f 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -31,12 +31,6 @@ public partial class MainWindow : WindowBase _config = AppManager.Instance.Config; _manager = new WindowNotificationManager(TopLevel.GetTopLevel(this)) { MaxItems = 3, Position = NotificationPosition.TopRight }; - if (_config.UiItem.AutoHideStartup) - { - this.ShowActivated = false; - this.WindowState = WindowState.Minimized; - } - this.KeyDown += MainWindow_KeyDown; menuSettingsSetUWP.Click += menuSettingsSetUWP_Click; menuPromotion.Click += menuPromotion_Click; @@ -184,6 +178,11 @@ public partial class MainWindow : WindowBase } menuAddServerViaScan.IsVisible = false; + if (_config.UiItem.AutoHideStartup) + { + this.WindowState = WindowState.Minimized; + } + AddHelpMenuItem(); } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml b/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml index dd0ac33117..30f74a14c6 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml @@ -18,7 +18,7 @@ Margin="{StaticResource Margin4}" ColumnDefinitions="Auto,Auto,Auto" DockPanel.Dock="Top" - RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto"> + RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto"> - + VerticalAlignment="Center" + Orientation="Horizontal"> + + + + + + + @@ -114,20 +142,20 @@ ().AppendEmpty(); if (!rulesItem.Id.IsNullOrEmpty()) { @@ -53,6 +54,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.RuleType, v => v.cmbRuleType.SelectedValue).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); }); diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml b/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml index 8475b8758f..7e51192e6d 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml @@ -209,7 +209,11 @@ Binding="{Binding Remarks}" Header="{x:Static resx:ResUI.LvRemarks}" /> + - + Header="domain / ip" /> diff --git a/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs index c42012758a..3fccddf075 100644 --- a/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -25,12 +25,6 @@ public partial class MainWindow _config = AppManager.Instance.Config; ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false); - if (_config.UiItem.AutoHideStartup) - { - this.ShowActivated = false; - this.WindowState = WindowState.Minimized; - } - App.Current.SessionEnding += Current_SessionEnding; this.Closing += MainWindow_Closing; this.PreviewKeyDown += MainWindow_PreviewKeyDown; @@ -164,6 +158,10 @@ public partial class MainWindow }); this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}"; + if (_config.UiItem.AutoHideStartup) + { + this.WindowState = WindowState.Minimized; + } if (!_config.GuiItem.EnableHWA) { diff --git a/v2rayn/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml b/v2rayn/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml index f24a38d704..acf1c7f243 100644 --- a/v2rayn/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml +++ b/v2rayn/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml @@ -26,6 +26,7 @@ + @@ -48,13 +49,19 @@ Margin="{StaticResource Margin4}" HorizontalAlignment="Left" Style="{StaticResource DefTextBox}" /> - + VerticalAlignment="Center" + Orientation="Horizontal"> + + + + + + ().AppendEmpty(); if (!rulesItem.Id.IsNullOrEmpty()) { @@ -45,6 +46,7 @@ public partial class RoutingRuleDetailsWindow this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.RuleType, v => v.cmbRuleType.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); }); diff --git a/v2rayn/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml b/v2rayn/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml index b26a89026b..9cc16bff17 100644 --- a/v2rayn/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml +++ b/v2rayn/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml @@ -301,7 +301,11 @@ Binding="{Binding Remarks}" Header="{x:Static resx:ResUI.LvRemarks}" /> + - + Header="domain / ip" />