mirror of
https://github.com/bolucat/Archive.git
synced 2025-10-13 03:44:39 +08:00
Update On Mon Jul 15 20:32:26 CEST 2024
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -703,3 +703,4 @@ Update On Thu Jul 11 20:30:51 CEST 2024
|
|||||||
Update On Fri Jul 12 20:34:05 CEST 2024
|
Update On Fri Jul 12 20:34:05 CEST 2024
|
||||||
Update On Sat Jul 13 20:28:46 CEST 2024
|
Update On Sat Jul 13 20:28:46 CEST 2024
|
||||||
Update On Sun Jul 14 20:40:18 CEST 2024
|
Update On Sun Jul 14 20:40:18 CEST 2024
|
||||||
|
Update On Mon Jul 15 20:32:15 CEST 2024
|
||||||
|
@@ -69,7 +69,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
|
|||||||
}
|
}
|
||||||
|
|
||||||
if groupOption.IncludeAllProviders {
|
if groupOption.IncludeAllProviders {
|
||||||
groupOption.Use = append(groupOption.Use, AllProviders...)
|
groupOption.Use = AllProviders
|
||||||
}
|
}
|
||||||
if groupOption.IncludeAllProxies {
|
if groupOption.IncludeAllProxies {
|
||||||
if groupOption.Filter != "" {
|
if groupOption.Filter != "" {
|
||||||
|
4
clash-nyanpasu/backend/Cargo.lock
generated
4
clash-nyanpasu/backend/Cargo.lock
generated
@@ -1779,9 +1779,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fast_image_resize"
|
name = "fast_image_resize"
|
||||||
version = "4.0.0"
|
version = "4.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02abb58c39fa9b20678cedabab49e6c4f6ecb7480d7cb5711496b9289184a875"
|
checksum = "89a06940fe3bab6e93dc275bb8a67cc833b70f4078124e7e7f7352f5c8470e63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"document-features",
|
"document-features",
|
||||||
|
@@ -108,7 +108,7 @@
|
|||||||
},
|
},
|
||||||
"windows": [],
|
"windows": [],
|
||||||
"security": {
|
"security": {
|
||||||
"csp": "script-src 'unsafe-eval' 'self'; default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; img-src data: 'self' https:;"
|
"csp": "script-src 'unsafe-eval' 'self'; default-src 'self' blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' http: https:;"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
clash-verge-rev/.github/workflows/release.yml
vendored
15
clash-verge-rev/.github/workflows/release.yml
vendored
@@ -258,12 +258,23 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
submit-to-winget:
|
submit-to-winget:
|
||||||
runs-on: windows-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [release-update]
|
needs: [release-update]
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Get Version
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install jq
|
||||||
|
echo "VERSION=$(cat package.json | jq '.version' | tr -d '"')" >> $GITHUB_ENV
|
||||||
- name: Submit to Winget
|
- name: Submit to Winget
|
||||||
uses: vedantmgoyal9/winget-releaser@main
|
uses: vedantmgoyal9/winget-releaser@main
|
||||||
with:
|
with:
|
||||||
identifier: ClashVergeRev.ClashVergeRev
|
identifier: ClashVergeRev.ClashVergeRev
|
||||||
|
version: ${{env.VERSION}}
|
||||||
|
release-tag: v${{env.VERSION}}
|
||||||
installers-regex: '_(arm64|x64|x86)-setup\.exe$'
|
installers-regex: '_(arm64|x64|x86)-setup\.exe$'
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.WINGET_TOKEN }}
|
||||||
|
@@ -1,3 +1,28 @@
|
|||||||
|
## v1.7.5
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- 展示局域网 IP 地址信息
|
||||||
|
- 在设置页面直接复制环境变量
|
||||||
|
- 优化服务模式安装逻辑
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
- 优化切换订阅速度
|
||||||
|
- 优化更改端口速度
|
||||||
|
|
||||||
|
### Bugs Fixes
|
||||||
|
|
||||||
|
- 调整 MacOS 托盘图标大小
|
||||||
|
- Trojan URI 解析错误
|
||||||
|
- 卡片拖动显示层级错误
|
||||||
|
- 代理绕过格式检查错误
|
||||||
|
- MacOS 下编辑器最大化失败
|
||||||
|
- MacOS 服务安装失败
|
||||||
|
- 更改窗口大小导致闪退的问题
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v1.7.3
|
## v1.7.3
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "clash-verge",
|
"name": "clash-verge",
|
||||||
"version": "1.7.3",
|
"version": "1.7.5",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tauri dev",
|
"dev": "tauri dev",
|
||||||
|
2
clash-verge-rev/src-tauri/Cargo.lock
generated
2
clash-verge-rev/src-tauri/Cargo.lock
generated
@@ -790,7 +790,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clash-verge"
|
name = "clash-verge"
|
||||||
version = "1.7.3"
|
version = "1.7.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"auto-launch",
|
"auto-launch",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "clash-verge"
|
name = "clash-verge"
|
||||||
version = "1.7.3"
|
version = "1.7.5"
|
||||||
description = "clash verge"
|
description = "clash verge"
|
||||||
authors = ["zzzgydi", "wonfen", "MystiPanda"]
|
authors = ["zzzgydi", "wonfen", "MystiPanda"]
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
@@ -191,11 +191,15 @@ pub fn init_config() -> Result<()> {
|
|||||||
/// after tauri setup
|
/// after tauri setup
|
||||||
pub fn init_resources() -> Result<()> {
|
pub fn init_resources() -> Result<()> {
|
||||||
let app_dir = dirs::app_home_dir()?;
|
let app_dir = dirs::app_home_dir()?;
|
||||||
|
let test_dir = app_dir.join("test");
|
||||||
let res_dir = dirs::app_resources_dir()?;
|
let res_dir = dirs::app_resources_dir()?;
|
||||||
|
|
||||||
if !app_dir.exists() {
|
if !app_dir.exists() {
|
||||||
let _ = fs::create_dir_all(&app_dir);
|
let _ = fs::create_dir_all(&app_dir);
|
||||||
}
|
}
|
||||||
|
if !test_dir.exists() {
|
||||||
|
let _ = fs::create_dir_all(&test_dir);
|
||||||
|
}
|
||||||
if !res_dir.exists() {
|
if !res_dir.exists() {
|
||||||
let _ = fs::create_dir_all(&res_dir);
|
let _ = fs::create_dir_all(&res_dir);
|
||||||
}
|
}
|
||||||
@@ -210,9 +214,10 @@ pub fn init_resources() -> Result<()> {
|
|||||||
for file in file_list.iter() {
|
for file in file_list.iter() {
|
||||||
let src_path = res_dir.join(file);
|
let src_path = res_dir.join(file);
|
||||||
let dest_path = app_dir.join(file);
|
let dest_path = app_dir.join(file);
|
||||||
|
let test_dest_path = test_dir.join(file);
|
||||||
|
|
||||||
let handle_copy = || {
|
let handle_copy = |dest: &PathBuf| {
|
||||||
match fs::copy(&src_path, &dest_path) {
|
match fs::copy(&src_path, dest) {
|
||||||
Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
|
Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!(target: "app", "failed to copy resources '{file}', {err}")
|
log::error!(target: "app", "failed to copy resources '{file}', {err}")
|
||||||
@@ -220,8 +225,11 @@ pub fn init_resources() -> Result<()> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if src_path.exists() && !test_dest_path.exists() {
|
||||||
|
handle_copy(&test_dest_path);
|
||||||
|
}
|
||||||
if src_path.exists() && !dest_path.exists() {
|
if src_path.exists() && !dest_path.exists() {
|
||||||
handle_copy();
|
handle_copy(&dest_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,14 +239,14 @@ pub fn init_resources() -> Result<()> {
|
|||||||
match (src_modified, dest_modified) {
|
match (src_modified, dest_modified) {
|
||||||
(Ok(src_modified), Ok(dest_modified)) => {
|
(Ok(src_modified), Ok(dest_modified)) => {
|
||||||
if src_modified > dest_modified {
|
if src_modified > dest_modified {
|
||||||
handle_copy();
|
handle_copy(&dest_path);
|
||||||
} else {
|
} else {
|
||||||
log::debug!(target: "app", "skipping resource copy '{file}'");
|
log::debug!(target: "app", "skipping resource copy '{file}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
log::debug!(target: "app", "failed to get modified '{file}'");
|
log::debug!(target: "app", "failed to get modified '{file}'");
|
||||||
handle_copy();
|
handle_copy(&dest_path);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "Clash Verge",
|
"productName": "Clash Verge",
|
||||||
"version": "1.7.3"
|
"version": "1.7.5"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"distDir": "../dist",
|
"distDir": "../dist",
|
||||||
|
@@ -11,6 +11,7 @@ export const Switch = styled((props: SwitchProps) => (
|
|||||||
width: 42,
|
width: 42,
|
||||||
height: 26,
|
height: 26,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
marginRight: 1,
|
||||||
"& .MuiSwitch-switchBase": {
|
"& .MuiSwitch-switchBase": {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
margin: 2,
|
margin: 2,
|
||||||
|
@@ -49,9 +49,8 @@ export const NetworkInterfaceViewer = forwardRef<DialogRef>((props, ref) => {
|
|||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
contentSx={{ width: 450, maxHeight: 330 }}
|
contentSx={{ width: 450, maxHeight: 330 }}
|
||||||
okBtn={t("Save")}
|
disableOk
|
||||||
cancelBtn={t("Cancel")}
|
cancelBtn={t("Close")}
|
||||||
onClose={() => setOpen(false)}
|
|
||||||
onCancel={() => setOpen(false)}
|
onCancel={() => setOpen(false)}
|
||||||
>
|
>
|
||||||
{networkInterfaces.map((item) => (
|
{networkInterfaces.map((item) => (
|
||||||
|
@@ -0,0 +1,97 @@
|
|||||||
|
import { KeyedMutator } from "swr";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useLockFn } from "ahooks";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { installService, uninstallService } from "@/services/cmds";
|
||||||
|
import { Notice } from "@/components/base";
|
||||||
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
status: "active" | "installed" | "unknown" | "uninstall";
|
||||||
|
mutate: KeyedMutator<"active" | "installed" | "unknown" | "uninstall">;
|
||||||
|
patchVerge: (value: Partial<IVergeConfig>) => Promise<void>;
|
||||||
|
onChangeData: (patch: Partial<IVergeConfig>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ServiceSwitcher = (props: Props) => {
|
||||||
|
const { status, mutate, patchVerge, onChangeData } = props;
|
||||||
|
|
||||||
|
const isActive = status === "active";
|
||||||
|
const isInstalled = status === "installed";
|
||||||
|
const isUninstall = status === "uninstall" || status === "unknown";
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [serviceLoading, setServiceLoading] = useState(false);
|
||||||
|
const [uninstallServiceLoaing, setUninstallServiceLoading] = useState(false);
|
||||||
|
|
||||||
|
const onInstallOrEnableService = useLockFn(async () => {
|
||||||
|
setServiceLoading(true);
|
||||||
|
try {
|
||||||
|
if (isUninstall) {
|
||||||
|
// install service
|
||||||
|
await installService();
|
||||||
|
await mutate();
|
||||||
|
setTimeout(() => {
|
||||||
|
mutate();
|
||||||
|
}, 2000);
|
||||||
|
Notice.success(t("Service Installed Successfully"));
|
||||||
|
setServiceLoading(false);
|
||||||
|
} else {
|
||||||
|
// enable or disable service
|
||||||
|
await patchVerge({ enable_service_mode: !isActive });
|
||||||
|
onChangeData({ enable_service_mode: !isActive });
|
||||||
|
await mutate();
|
||||||
|
setTimeout(() => {
|
||||||
|
mutate();
|
||||||
|
}, 2000);
|
||||||
|
setServiceLoading(false);
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
await mutate();
|
||||||
|
Notice.error(err.message || err.toString());
|
||||||
|
setServiceLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onUninstallService = useLockFn(async () => {
|
||||||
|
setUninstallServiceLoading(true);
|
||||||
|
try {
|
||||||
|
await uninstallService();
|
||||||
|
await mutate();
|
||||||
|
setTimeout(() => {
|
||||||
|
mutate();
|
||||||
|
}, 2000);
|
||||||
|
Notice.success(t("Service Uninstalled Successfully"));
|
||||||
|
setUninstallServiceLoading(false);
|
||||||
|
} catch (err: any) {
|
||||||
|
await mutate();
|
||||||
|
Notice.error(err.message || err.toString());
|
||||||
|
setUninstallServiceLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<LoadingButton
|
||||||
|
size="small"
|
||||||
|
variant={isUninstall ? "outlined" : "contained"}
|
||||||
|
onClick={onInstallOrEnableService}
|
||||||
|
loading={serviceLoading}
|
||||||
|
>
|
||||||
|
{isActive ? t("Disable") : isInstalled ? t("Enable") : t("Install")}
|
||||||
|
</LoadingButton>
|
||||||
|
{isInstalled && (
|
||||||
|
<LoadingButton
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
sx={{ ml: 1 }}
|
||||||
|
onClick={onUninstallService}
|
||||||
|
loading={uninstallServiceLoaing}
|
||||||
|
>
|
||||||
|
{t("Uninstall")}
|
||||||
|
</LoadingButton>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@@ -1,129 +0,0 @@
|
|||||||
import useSWR from "swr";
|
|
||||||
import { forwardRef, useImperativeHandle, useState } from "react";
|
|
||||||
import { useLockFn } from "ahooks";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { Button, Stack, Typography } from "@mui/material";
|
|
||||||
import {
|
|
||||||
checkService,
|
|
||||||
installService,
|
|
||||||
uninstallService,
|
|
||||||
patchVergeConfig,
|
|
||||||
} from "@/services/cmds";
|
|
||||||
import { BaseDialog, DialogRef, Notice } from "@/components/base";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
enable: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ServiceViewer = forwardRef<DialogRef, Props>((props, ref) => {
|
|
||||||
const { enable } = props;
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
const { data: status, mutate: mutateCheck } = useSWR(
|
|
||||||
"checkService",
|
|
||||||
checkService,
|
|
||||||
{
|
|
||||||
revalidateIfStale: false,
|
|
||||||
shouldRetryOnError: false,
|
|
||||||
focusThrottleInterval: 36e5, // 1 hour
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
open: () => setOpen(true),
|
|
||||||
close: () => setOpen(false),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const state = status != null ? status : "pending";
|
|
||||||
|
|
||||||
const onInstall = useLockFn(async () => {
|
|
||||||
try {
|
|
||||||
await installService();
|
|
||||||
await mutateCheck();
|
|
||||||
setOpen(false);
|
|
||||||
setTimeout(() => {
|
|
||||||
mutateCheck();
|
|
||||||
}, 2000);
|
|
||||||
Notice.success(t("Service Installed Successfully"));
|
|
||||||
} catch (err: any) {
|
|
||||||
mutateCheck();
|
|
||||||
Notice.error(err.message || err.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const onUninstall = useLockFn(async () => {
|
|
||||||
try {
|
|
||||||
if (enable) {
|
|
||||||
await patchVergeConfig({ enable_service_mode: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
await uninstallService();
|
|
||||||
mutateCheck();
|
|
||||||
setOpen(false);
|
|
||||||
Notice.success(t("Service Uninstalled Successfully"));
|
|
||||||
} catch (err: any) {
|
|
||||||
mutateCheck();
|
|
||||||
Notice.error(err.message || err.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// fix unhandled error of the service mode
|
|
||||||
const onDisable = useLockFn(async () => {
|
|
||||||
try {
|
|
||||||
await patchVergeConfig({ enable_service_mode: false });
|
|
||||||
mutateCheck();
|
|
||||||
setOpen(false);
|
|
||||||
} catch (err: any) {
|
|
||||||
mutateCheck();
|
|
||||||
Notice.error(err.message || err.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<BaseDialog
|
|
||||||
open={open}
|
|
||||||
title={t("Service Mode")}
|
|
||||||
contentSx={{ width: 360, userSelect: "text" }}
|
|
||||||
disableFooter
|
|
||||||
onClose={() => setOpen(false)}
|
|
||||||
>
|
|
||||||
<Typography>
|
|
||||||
{t("Current State")}: {t(state)}
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
{(state === "unknown" || state === "uninstall") && (
|
|
||||||
<Typography>
|
|
||||||
{t(
|
|
||||||
"Information: Please make sure that the Clash Verge Service is installed and enabled"
|
|
||||||
)}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Stack
|
|
||||||
direction="row"
|
|
||||||
spacing={1}
|
|
||||||
sx={{ mt: 4, justifyContent: "flex-end" }}
|
|
||||||
>
|
|
||||||
{state === "uninstall" && enable && (
|
|
||||||
<Button variant="contained" onClick={onDisable}>
|
|
||||||
{t("Disable Service Mode")}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{state === "uninstall" && (
|
|
||||||
<Button variant="contained" onClick={onInstall}>
|
|
||||||
{t("Install")}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(state === "active" || state === "installed") && (
|
|
||||||
<Button variant="outlined" onClick={onUninstall}>
|
|
||||||
{t("Uninstall")}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Stack>
|
|
||||||
</BaseDialog>
|
|
||||||
);
|
|
||||||
});
|
|
@@ -1,13 +1,13 @@
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { PrivacyTipRounded, SettingsRounded } from "@mui/icons-material";
|
import { SettingsRounded } from "@mui/icons-material";
|
||||||
import { checkService } from "@/services/cmds";
|
import { checkService } from "@/services/cmds";
|
||||||
import { useVerge } from "@/hooks/use-verge";
|
import { useVerge } from "@/hooks/use-verge";
|
||||||
import { DialogRef, Switch } from "@/components/base";
|
import { DialogRef, Notice, Switch } from "@/components/base";
|
||||||
import { SettingList, SettingItem } from "./mods/setting-comp";
|
import { SettingList, SettingItem } from "./mods/setting-comp";
|
||||||
import { GuardState } from "./mods/guard-state";
|
import { GuardState } from "./mods/guard-state";
|
||||||
import { ServiceViewer } from "./mods/service-viewer";
|
import { ServiceSwitcher } from "./mods/service-switcher";
|
||||||
import { SysproxyViewer } from "./mods/sysproxy-viewer";
|
import { SysproxyViewer } from "./mods/sysproxy-viewer";
|
||||||
import { TunViewer } from "./mods/tun-viewer";
|
import { TunViewer } from "./mods/tun-viewer";
|
||||||
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
|
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
|
||||||
@@ -20,22 +20,23 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { verge, mutateVerge, patchVerge } = useVerge();
|
const { verge, mutateVerge, patchVerge } = useVerge();
|
||||||
|
|
||||||
// service mode
|
// service mode
|
||||||
const { data: serviceStatus } = useSWR("checkService", checkService, {
|
const { data: serviceStatus, mutate: mutateServiceStatus } = useSWR(
|
||||||
revalidateIfStale: false,
|
"checkService",
|
||||||
shouldRetryOnError: false,
|
checkService,
|
||||||
focusThrottleInterval: 36e5, // 1 hour
|
{
|
||||||
});
|
revalidateIfStale: false,
|
||||||
|
shouldRetryOnError: false,
|
||||||
|
focusThrottleInterval: 36e5, // 1 hour
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const serviceRef = useRef<DialogRef>(null);
|
|
||||||
const sysproxyRef = useRef<DialogRef>(null);
|
const sysproxyRef = useRef<DialogRef>(null);
|
||||||
const tunRef = useRef<DialogRef>(null);
|
const tunRef = useRef<DialogRef>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
enable_tun_mode,
|
enable_tun_mode,
|
||||||
enable_auto_launch,
|
enable_auto_launch,
|
||||||
enable_service_mode,
|
|
||||||
enable_silent_start,
|
enable_silent_start,
|
||||||
enable_system_proxy,
|
enable_system_proxy,
|
||||||
} = verge ?? {};
|
} = verge ?? {};
|
||||||
@@ -49,7 +50,6 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
<SettingList title={t("System Setting")}>
|
<SettingList title={t("System Setting")}>
|
||||||
<SysproxyViewer ref={sysproxyRef} />
|
<SysproxyViewer ref={sysproxyRef} />
|
||||||
<TunViewer ref={tunRef} />
|
<TunViewer ref={tunRef} />
|
||||||
<ServiceViewer ref={serviceRef} enable={!!enable_service_mode} />
|
|
||||||
|
|
||||||
<SettingItem
|
<SettingItem
|
||||||
label={t("Tun Mode")}
|
label={t("Tun Mode")}
|
||||||
@@ -66,38 +66,33 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
valueProps="checked"
|
valueProps="checked"
|
||||||
onCatch={onError}
|
onCatch={onError}
|
||||||
onFormat={onSwitchFormat}
|
onFormat={onSwitchFormat}
|
||||||
onChange={(e) => onChangeData({ enable_tun_mode: e })}
|
onChange={(e) => {
|
||||||
onGuard={(e) => patchVerge({ enable_tun_mode: e })}
|
if (serviceStatus !== "active") {
|
||||||
|
onChangeData({ enable_tun_mode: false });
|
||||||
|
} else {
|
||||||
|
onChangeData({ enable_tun_mode: e });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onGuard={(e) => {
|
||||||
|
if (serviceStatus !== "active" && e) {
|
||||||
|
Notice.error(t("Please Enable Service Mode"));
|
||||||
|
return Promise.resolve();
|
||||||
|
} else {
|
||||||
|
return patchVerge({ enable_tun_mode: e });
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Switch edge="end" />
|
<Switch edge="end" />
|
||||||
</GuardState>
|
</GuardState>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
<SettingItem
|
<SettingItem label={t("Service Mode")}>
|
||||||
label={t("Service Mode")}
|
<ServiceSwitcher
|
||||||
extra={
|
status={serviceStatus ?? "unknown"}
|
||||||
<TooltipIcon
|
mutate={mutateServiceStatus}
|
||||||
title={t("Service Mode Info")}
|
patchVerge={patchVerge}
|
||||||
icon={PrivacyTipRounded}
|
onChangeData={onChangeData}
|
||||||
onClick={() => serviceRef.current?.open()}
|
/>
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<GuardState
|
|
||||||
value={enable_service_mode ?? false}
|
|
||||||
valueProps="checked"
|
|
||||||
onCatch={onError}
|
|
||||||
onFormat={onSwitchFormat}
|
|
||||||
onChange={(e) => onChangeData({ enable_service_mode: e })}
|
|
||||||
onGuard={(e) => patchVerge({ enable_service_mode: e })}
|
|
||||||
>
|
|
||||||
<Switch
|
|
||||||
edge="end"
|
|
||||||
disabled={
|
|
||||||
serviceStatus !== "active" && serviceStatus !== "installed"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</GuardState>
|
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
<SettingItem
|
<SettingItem
|
||||||
|
@@ -266,7 +266,7 @@
|
|||||||
"Restart": "Restart",
|
"Restart": "Restart",
|
||||||
"Release Version": "Release Version",
|
"Release Version": "Release Version",
|
||||||
"Alpha Version": "Alpha Version",
|
"Alpha Version": "Alpha Version",
|
||||||
"Tun mode requires": "Tun mode requires",
|
"Please Enable Service Mode": "Please Install and Enable Service Mode First",
|
||||||
"Grant": "Grant",
|
"Grant": "Grant",
|
||||||
"Open UWP tool": "Open UWP tool",
|
"Open UWP tool": "Open UWP tool",
|
||||||
"Open UWP tool Info": "Since Windows 8, UWP apps (such as Microsoft Store) are restricted from directly accessing local host network services, and this tool can be used to bypass this restriction",
|
"Open UWP tool Info": "Since Windows 8, UWP apps (such as Microsoft Store) are restricted from directly accessing local host network services, and this tool can be used to bypass this restriction",
|
||||||
|
@@ -261,7 +261,7 @@
|
|||||||
"Restart": "راهاندازی مجدد",
|
"Restart": "راهاندازی مجدد",
|
||||||
"Release Version": "نسخه نهایی",
|
"Release Version": "نسخه نهایی",
|
||||||
"Alpha Version": "نسخه آلفا",
|
"Alpha Version": "نسخه آلفا",
|
||||||
"Tun mode requires": "Tun mode نیاز دارد",
|
"Please Install and Enable Service Mode First": "لطفاً ابتدا حالت سرویس را نصب و فعال کنید",
|
||||||
"Grant": "اعطا",
|
"Grant": "اعطا",
|
||||||
"Open UWP tool": "باز کردن ابزار UWP",
|
"Open UWP tool": "باز کردن ابزار UWP",
|
||||||
"Open UWP tool Info": "از ویندوز 8 به بعد، برنامههای UWP (مانند Microsoft Store) از دسترسی مستقیم به خدمات شبکه محلی محدود شدهاند و این ابزار میتواند برای دور زدن این محدودیت استفاده شود",
|
"Open UWP tool Info": "از ویندوز 8 به بعد، برنامههای UWP (مانند Microsoft Store) از دسترسی مستقیم به خدمات شبکه محلی محدود شدهاند و این ابزار میتواند برای دور زدن این محدودیت استفاده شود",
|
||||||
|
@@ -264,7 +264,7 @@
|
|||||||
"Restart": "Перезапуск",
|
"Restart": "Перезапуск",
|
||||||
"Release Version": "Официальная версия",
|
"Release Version": "Официальная версия",
|
||||||
"Alpha Version": "Альфа-версия",
|
"Alpha Version": "Альфа-версия",
|
||||||
"Tun mode requires": "Требуется Режим туннеля",
|
"Please Enable Service Mode": "Пожалуйста, сначала установите и включите режим обслуживания",
|
||||||
"Grant": "Предоставить",
|
"Grant": "Предоставить",
|
||||||
"Open UWP tool": "Открыть UWP инструмент",
|
"Open UWP tool": "Открыть UWP инструмент",
|
||||||
"Open UWP tool Info": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение",
|
"Open UWP tool Info": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение",
|
||||||
|
@@ -266,7 +266,7 @@
|
|||||||
"Restart": "重启内核",
|
"Restart": "重启内核",
|
||||||
"Release Version": "正式版",
|
"Release Version": "正式版",
|
||||||
"Alpha Version": "预览版",
|
"Alpha Version": "预览版",
|
||||||
"Tun mode requires": "如需启用 Tun 模式需要授权",
|
"Please Enable Service Mode": "请先安装并启用服务模式",
|
||||||
"Grant": "授权",
|
"Grant": "授权",
|
||||||
"Open UWP tool": "UWP 工具",
|
"Open UWP tool": "UWP 工具",
|
||||||
"Open UWP tool Info": "Windows 8开始限制 UWP 应用(如微软商店)直接访问本地主机的网络服务,使用此工具可绕过该限制",
|
"Open UWP tool Info": "Windows 8开始限制 UWP 应用(如微软商店)直接访问本地主机的网络服务,使用此工具可绕过该限制",
|
||||||
|
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=lua
|
PKG_NAME:=lua
|
||||||
PKG_VERSION:=5.1.5
|
PKG_VERSION:=5.1.5
|
||||||
PKG_RELEASE:=10
|
PKG_RELEASE:=11
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://www.lua.org/ftp/ \
|
PKG_SOURCE_URL:=https://www.lua.org/ftp/ \
|
||||||
|
@@ -8,7 +8,6 @@ Including it allows multiple lua versions to coexist.
|
|||||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
---
|
---
|
||||||
|
|
||||||
diff --git a/Makefile b/Makefile
|
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -41,10 +41,10 @@ RANLIB= ranlib
|
@@ -41,10 +41,10 @@ RANLIB= ranlib
|
||||||
@@ -42,7 +41,7 @@ rename to doc/luac5.1.1
|
|||||||
diff --git a/src/Makefile b/src/Makefile
|
diff --git a/src/Makefile b/src/Makefile
|
||||||
--- a/src/Makefile
|
--- a/src/Makefile
|
||||||
+++ b/src/Makefile
|
+++ b/src/Makefile
|
||||||
@@ -29,10 +29,10 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
|
@@ -29,10 +29,10 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ld
|
||||||
LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
|
LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
|
||||||
lstrlib.o loadlib.o linit.o
|
lstrlib.o loadlib.o linit.o
|
||||||
|
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
diff --git a/src/lnum.c b/src/lnum.c
|
|
||||||
index 1456b6a2ed23..b0632b04c2b7 100644
|
|
||||||
--- a/src/lnum.c
|
--- a/src/lnum.c
|
||||||
+++ b/src/lnum.c
|
+++ b/src/lnum.c
|
||||||
@@ -127,6 +127,8 @@ static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) {
|
@@ -127,6 +127,8 @@ static int luaO_str2i (const char *s, lu
|
||||||
#else
|
#else
|
||||||
return 0; /* Reject the number */
|
return 0; /* Reject the number */
|
||||||
#endif
|
#endif
|
||||||
@@ -11,7 +9,7 @@ index 1456b6a2ed23..b0632b04c2b7 100644
|
|||||||
}
|
}
|
||||||
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
|
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
|
||||||
return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
|
return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
|
||||||
@@ -310,3 +312,13 @@ int try_unmint( lua_Integer *r, lua_Integer ib ) {
|
@@ -310,3 +312,13 @@ int try_unmint( lua_Integer *r, lua_Inte
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,8 +23,6 @@ index 1456b6a2ed23..b0632b04c2b7 100644
|
|||||||
+ return (unsigned LUA_INTEGER)v;
|
+ return (unsigned LUA_INTEGER)v;
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#endif
|
||||||
diff --git a/src/lnum_config.h b/src/lnum_config.h
|
|
||||||
index 19d7a4231a49..1092eead6629 100644
|
|
||||||
--- a/src/lnum_config.h
|
--- a/src/lnum_config.h
|
||||||
+++ b/src/lnum_config.h
|
+++ b/src/lnum_config.h
|
||||||
@@ -141,7 +141,12 @@
|
@@ -141,7 +141,12 @@
|
||||||
@@ -43,6 +39,3 @@ index 19d7a4231a49..1092eead6629 100644
|
|||||||
#endif
|
#endif
|
||||||
#ifndef LUA_INTEGER_MIN
|
#ifndef LUA_INTEGER_MIN
|
||||||
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
|
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
|
||||||
--
|
|
||||||
1.9.1
|
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#if defined(LUA_USE_MACOSX)
|
#if defined(LUA_USE_MACOSX)
|
||||||
--- a/src/Makefile
|
--- a/src/Makefile
|
||||||
+++ b/src/Makefile
|
+++ b/src/Makefile
|
||||||
@@ -17,6 +17,7 @@
|
@@ -17,6 +17,7 @@ LIBS= -lm $(MYLIBS)
|
||||||
MYCFLAGS=
|
MYCFLAGS=
|
||||||
MYLDFLAGS=
|
MYLDFLAGS=
|
||||||
MYLIBS=
|
MYLIBS=
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
|
# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@
|
@@ -75,7 +76,7 @@ echo:
|
||||||
@echo "MYLIBS = $(MYLIBS)"
|
@echo "MYLIBS = $(MYLIBS)"
|
||||||
|
|
||||||
# convenience targets for popular platforms
|
# convenience targets for popular platforms
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
none:
|
none:
|
||||||
@echo "Please choose a platform:"
|
@echo "Please choose a platform:"
|
||||||
@echo " $(PLATS)"
|
@echo " $(PLATS)"
|
||||||
@@ -90,16 +91,16 @@
|
@@ -90,16 +91,16 @@ bsd:
|
||||||
$(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
|
$(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
|
||||||
|
|
||||||
freebsd:
|
freebsd:
|
||||||
|
19
lede/package/utils/lua/patches-host/400-CVE-2014-5461.patch
Normal file
19
lede/package/utils/lua/patches-host/400-CVE-2014-5461.patch
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
From: Enrico Tassi <gareuselesinge@debian.org>
|
||||||
|
Date: Tue, 26 Aug 2014 16:20:55 +0200
|
||||||
|
Subject: Fix stack overflow in vararg functions
|
||||||
|
|
||||||
|
---
|
||||||
|
src/ldo.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/src/ldo.c
|
||||||
|
+++ b/src/ldo.c
|
||||||
|
@@ -274,7 +274,7 @@ int luaD_precall (lua_State *L, StkId fu
|
||||||
|
CallInfo *ci;
|
||||||
|
StkId st, base;
|
||||||
|
Proto *p = cl->p;
|
||||||
|
- luaD_checkstack(L, p->maxstacksize);
|
||||||
|
+ luaD_checkstack(L, p->maxstacksize + p->numparams);
|
||||||
|
func = restorestack(L, funcr);
|
||||||
|
if (!p->is_vararg) { /* no varargs? */
|
||||||
|
base = func + 1;
|
@@ -8,7 +8,6 @@ Including it allows multiple lua versions to coexist.
|
|||||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
---
|
---
|
||||||
|
|
||||||
diff --git a/Makefile b/Makefile
|
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -41,10 +41,10 @@ RANLIB= ranlib
|
@@ -41,10 +41,10 @@ RANLIB= ranlib
|
||||||
@@ -42,7 +41,7 @@ rename to doc/luac5.1.1
|
|||||||
diff --git a/src/Makefile b/src/Makefile
|
diff --git a/src/Makefile b/src/Makefile
|
||||||
--- a/src/Makefile
|
--- a/src/Makefile
|
||||||
+++ b/src/Makefile
|
+++ b/src/Makefile
|
||||||
@@ -29,10 +29,10 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
|
@@ -29,10 +29,10 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ld
|
||||||
LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
|
LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
|
||||||
lstrlib.o loadlib.o linit.o
|
lstrlib.o loadlib.o linit.o
|
||||||
|
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
diff --git a/src/lnum.c b/src/lnum.c
|
|
||||||
index 1456b6a2ed23..b0632b04c2b7 100644
|
|
||||||
--- a/src/lnum.c
|
--- a/src/lnum.c
|
||||||
+++ b/src/lnum.c
|
+++ b/src/lnum.c
|
||||||
@@ -127,6 +127,8 @@ static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) {
|
@@ -127,6 +127,8 @@ static int luaO_str2i (const char *s, lu
|
||||||
#else
|
#else
|
||||||
return 0; /* Reject the number */
|
return 0; /* Reject the number */
|
||||||
#endif
|
#endif
|
||||||
@@ -11,7 +9,7 @@ index 1456b6a2ed23..b0632b04c2b7 100644
|
|||||||
}
|
}
|
||||||
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
|
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
|
||||||
return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
|
return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
|
||||||
@@ -310,3 +312,13 @@ int try_unmint( lua_Integer *r, lua_Integer ib ) {
|
@@ -310,3 +312,13 @@ int try_unmint( lua_Integer *r, lua_Inte
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,8 +23,6 @@ index 1456b6a2ed23..b0632b04c2b7 100644
|
|||||||
+ return (unsigned LUA_INTEGER)v;
|
+ return (unsigned LUA_INTEGER)v;
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#endif
|
||||||
diff --git a/src/lnum_config.h b/src/lnum_config.h
|
|
||||||
index 19d7a4231a49..1092eead6629 100644
|
|
||||||
--- a/src/lnum_config.h
|
--- a/src/lnum_config.h
|
||||||
+++ b/src/lnum_config.h
|
+++ b/src/lnum_config.h
|
||||||
@@ -141,7 +141,12 @@
|
@@ -141,7 +141,12 @@
|
||||||
@@ -43,6 +39,3 @@ index 19d7a4231a49..1092eead6629 100644
|
|||||||
#endif
|
#endif
|
||||||
#ifndef LUA_INTEGER_MIN
|
#ifndef LUA_INTEGER_MIN
|
||||||
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
|
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
|
||||||
--
|
|
||||||
1.9.1
|
|
||||||
|
|
||||||
|
19
lede/package/utils/lua/patches/400-CVE-2014-5461.patch
Normal file
19
lede/package/utils/lua/patches/400-CVE-2014-5461.patch
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
From: Enrico Tassi <gareuselesinge@debian.org>
|
||||||
|
Date: Tue, 26 Aug 2014 16:20:55 +0200
|
||||||
|
Subject: Fix stack overflow in vararg functions
|
||||||
|
|
||||||
|
---
|
||||||
|
src/ldo.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/src/ldo.c
|
||||||
|
+++ b/src/ldo.c
|
||||||
|
@@ -274,7 +274,7 @@ int luaD_precall (lua_State *L, StkId fu
|
||||||
|
CallInfo *ci;
|
||||||
|
StkId st, base;
|
||||||
|
Proto *p = cl->p;
|
||||||
|
- luaD_checkstack(L, p->maxstacksize);
|
||||||
|
+ luaD_checkstack(L, p->maxstacksize + p->numparams);
|
||||||
|
func = restorestack(L, funcr);
|
||||||
|
if (!p->is_vararg) { /* no varargs? */
|
||||||
|
base = func + 1;
|
@@ -88,10 +88,10 @@ type BBRSender struct {
|
|||||||
currentRoundTripEnd int64
|
currentRoundTripEnd int64
|
||||||
|
|
||||||
// Tracks the maximum bandwidth over the multiple recent round-trips.
|
// Tracks the maximum bandwidth over the multiple recent round-trips.
|
||||||
maxBandwidth WindowedFilter[uint64]
|
maxBandwidth WindowedFilter[int64]
|
||||||
|
|
||||||
// Tracks the maximum number of bytes acked faster than the sending rate.
|
// Tracks the maximum number of bytes acked faster than the sending rate.
|
||||||
maxAckHeight WindowedFilter[uint64]
|
maxAckHeight WindowedFilter[int64]
|
||||||
|
|
||||||
// The time this aggregation started and the number of bytes acked during it.
|
// The time this aggregation started and the number of bytes acked during it.
|
||||||
aggregationEpochStartTime time.Time
|
aggregationEpochStartTime time.Time
|
||||||
@@ -158,7 +158,7 @@ type BBRSender struct {
|
|||||||
isAtFullBandwidth bool
|
isAtFullBandwidth bool
|
||||||
|
|
||||||
// Number of rounds during which there was no significant bandwidth increase.
|
// Number of rounds during which there was no significant bandwidth increase.
|
||||||
roundsWithoutBandwidthGain uint64
|
roundsWithoutBandwidthGain int64
|
||||||
|
|
||||||
// The bandwidth compared to which the increase is measured.
|
// The bandwidth compared to which the increase is measured.
|
||||||
bandwidthAtLastRound int64
|
bandwidthAtLastRound int64
|
||||||
@@ -234,7 +234,7 @@ func (b *BBRSender) IsProbingForMoreBandwidth() bool {
|
|||||||
return b.mode == modeProbeBW
|
return b.mode == modeProbeBW
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BBRSender) AdjustNetworkParameters(bandwidth uint64, rtt time.Duration) {
|
func (b *BBRSender) AdjustNetworkParameters(bandwidth int64, rtt time.Duration) {
|
||||||
if bandwidth > 0 {
|
if bandwidth > 0 {
|
||||||
b.maxBandwidth.Update(bandwidth, b.roundTripCount)
|
b.maxBandwidth.Update(bandwidth, b.roundTripCount)
|
||||||
}
|
}
|
||||||
@@ -276,8 +276,7 @@ func (b *BBRSender) PacingRate(bytesInFlight int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BBRSender) BandwidthEstimate() int64 {
|
func (b *BBRSender) BandwidthEstimate() int64 {
|
||||||
// Implementation here
|
return b.maxBandwidth.GetBest()
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BBRSender) GetCongestionWindow() int64 {
|
func (b *BBRSender) GetCongestionWindow() int64 {
|
||||||
@@ -286,7 +285,6 @@ func (b *BBRSender) GetCongestionWindow() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BBRSender) GetSlowStartThreshold() int64 {
|
func (b *BBRSender) GetSlowStartThreshold() int64 {
|
||||||
// Implementation here
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,8 +297,10 @@ func (b *BBRSender) NumStartupRTTs() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BBRSender) GetMinRTT() time.Duration {
|
func (b *BBRSender) GetMinRTT() time.Duration {
|
||||||
// Implementation here
|
if b.minRTT != 0 {
|
||||||
return 0
|
return b.minRTT
|
||||||
|
}
|
||||||
|
return b.rttStats.SmoothedRTT()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BBRSender) IsAtFullBandwidth() bool {
|
func (b *BBRSender) IsAtFullBandwidth() bool {
|
||||||
|
@@ -69,7 +69,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
|
|||||||
}
|
}
|
||||||
|
|
||||||
if groupOption.IncludeAllProviders {
|
if groupOption.IncludeAllProviders {
|
||||||
groupOption.Use = append(groupOption.Use, AllProviders...)
|
groupOption.Use = AllProviders
|
||||||
}
|
}
|
||||||
if groupOption.IncludeAllProxies {
|
if groupOption.IncludeAllProxies {
|
||||||
if groupOption.Filter != "" {
|
if groupOption.Filter != "" {
|
||||||
|
@@ -740,8 +740,7 @@ return view.extend({
|
|||||||
|
|
||||||
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
||||||
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
||||||
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
|
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
|
||||||
'Can be overrides by <code>rules.[].client_subnet</code>. Will overrides <code>dns.client_subnet</code>.'));
|
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
/* DNS servers end */
|
/* DNS servers end */
|
||||||
|
|
||||||
@@ -949,8 +948,7 @@ return view.extend({
|
|||||||
|
|
||||||
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
||||||
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
||||||
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
|
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
|
||||||
'Will overrides <code>dns.client_subnet</code> and <code>servers.[].client_subnet</code>.'));
|
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
/* DNS rules end */
|
/* DNS rules end */
|
||||||
/* Custom routing settings end */
|
/* Custom routing settings end */
|
||||||
|
@@ -479,8 +479,7 @@ return view.extend({
|
|||||||
|
|
||||||
o = s.option(form.Value, 'tls_sni', _('TLS SNI'),
|
o = s.option(form.Value, 'tls_sni', _('TLS SNI'),
|
||||||
_('Used to verify the hostname on the returned certificates unless insecure is given.'));
|
_('Used to verify the hostname on the returned certificates unless insecure is given.'));
|
||||||
o.depends({'tls': '1', 'tls_reality': '0'});
|
o.depends('tls', '1');
|
||||||
o.depends({'tls': '1', 'tls_reality': null});
|
|
||||||
o.modalonly = true;
|
o.modalonly = true;
|
||||||
|
|
||||||
o = s.option(form.DynamicList, 'tls_alpn', _('TLS ALPN'),
|
o = s.option(form.DynamicList, 'tls_alpn', _('TLS ALPN'),
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -40,14 +40,15 @@ chain input {
|
|||||||
iifname {{ tun_name }} counter accept comment "!{{ cfgname }}: accept tun input"
|
iifname {{ tun_name }} counter accept comment "!{{ cfgname }}: accept tun input"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%
|
{%
|
||||||
uci.foreach(cfgname, 'server', (s) => {
|
if (auto_firewall === '1')
|
||||||
if (s.enabled !== '1')
|
uci.foreach(cfgname, 'server', (s) => {
|
||||||
return;
|
if (s.enabled !== '1')
|
||||||
|
return;
|
||||||
|
|
||||||
let proto = s.network || '{ tcp, udp }';
|
let proto = s.network || '{ tcp, udp }';
|
||||||
printf(' meta l4proto %s th dport %s counter accept comment "!%s: accept server %s"\n',
|
printf(' meta l4proto %s th dport %s counter accept comment "!%s: accept server %s"\n',
|
||||||
proto, s.port, cfgname, s['.name']);
|
proto, s.port, cfgname, s['.name']);
|
||||||
});
|
});
|
||||||
%}
|
%}
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@@ -740,8 +740,7 @@ return view.extend({
|
|||||||
|
|
||||||
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
||||||
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
||||||
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
|
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
|
||||||
'Can be overrides by <code>rules.[].client_subnet</code>. Will overrides <code>dns.client_subnet</code>.'));
|
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
/* DNS servers end */
|
/* DNS servers end */
|
||||||
|
|
||||||
@@ -949,8 +948,7 @@ return view.extend({
|
|||||||
|
|
||||||
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
|
||||||
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
|
||||||
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
|
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
|
||||||
'Will overrides <code>dns.client_subnet</code> and <code>servers.[].client_subnet</code>.'));
|
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
/* DNS rules end */
|
/* DNS rules end */
|
||||||
/* Custom routing settings end */
|
/* Custom routing settings end */
|
||||||
|
@@ -479,8 +479,7 @@ return view.extend({
|
|||||||
|
|
||||||
o = s.option(form.Value, 'tls_sni', _('TLS SNI'),
|
o = s.option(form.Value, 'tls_sni', _('TLS SNI'),
|
||||||
_('Used to verify the hostname on the returned certificates unless insecure is given.'));
|
_('Used to verify the hostname on the returned certificates unless insecure is given.'));
|
||||||
o.depends({'tls': '1', 'tls_reality': '0'});
|
o.depends('tls', '1');
|
||||||
o.depends({'tls': '1', 'tls_reality': null});
|
|
||||||
o.modalonly = true;
|
o.modalonly = true;
|
||||||
|
|
||||||
o = s.option(form.DynamicList, 'tls_alpn', _('TLS ALPN'),
|
o = s.option(form.DynamicList, 'tls_alpn', _('TLS ALPN'),
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -40,14 +40,15 @@ chain input {
|
|||||||
iifname {{ tun_name }} counter accept comment "!{{ cfgname }}: accept tun input"
|
iifname {{ tun_name }} counter accept comment "!{{ cfgname }}: accept tun input"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%
|
{%
|
||||||
uci.foreach(cfgname, 'server', (s) => {
|
if (auto_firewall === '1')
|
||||||
if (s.enabled !== '1')
|
uci.foreach(cfgname, 'server', (s) => {
|
||||||
return;
|
if (s.enabled !== '1')
|
||||||
|
return;
|
||||||
|
|
||||||
let proto = s.network || '{ tcp, udp }';
|
let proto = s.network || '{ tcp, udp }';
|
||||||
printf(' meta l4proto %s th dport %s counter accept comment "!%s: accept server %s"\n',
|
printf(' meta l4proto %s th dport %s counter accept comment "!%s: accept server %s"\n',
|
||||||
proto, s.port, cfgname, s['.name']);
|
proto, s.port, cfgname, s['.name']);
|
||||||
});
|
});
|
||||||
%}
|
%}
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@@ -916,7 +916,8 @@ add_firewall_rule() {
|
|||||||
|
|
||||||
WAN_IP=$(get_wan_ip)
|
WAN_IP=$(get_wan_ip)
|
||||||
if [ -n "${WAN_IP}" ]; then
|
if [ -n "${WAN_IP}" ]; then
|
||||||
[ -n "${is_tproxy}" ] && nft "add rule inet fw4 PSW_MANGLE ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\"" || nft "add rule inet fw4 PSW_NAT ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\""
|
nft "add rule inet fw4 PSW_MANGLE ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\""
|
||||||
|
[ -z "${is_tproxy}" ] && nft "add rule inet fw4 PSW_NAT ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\""
|
||||||
fi
|
fi
|
||||||
unset WAN_IP
|
unset WAN_IP
|
||||||
|
|
||||||
|
4
shadowsocks-rust/Cargo.lock
generated
4
shadowsocks-rust/Cargo.lock
generated
@@ -308,9 +308,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake3"
|
name = "blake3"
|
||||||
version = "1.5.2"
|
version = "1.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92"
|
checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
@@ -30,13 +30,13 @@ define Download/geosite
|
|||||||
HASH:=dbaba085b1de1b8b875f3db78fb367aef080f24993af01abe21f4d4ba99048be
|
HASH:=dbaba085b1de1b8b875f3db78fb367aef080f24993af01abe21f4d4ba99048be
|
||||||
endef
|
endef
|
||||||
|
|
||||||
GEOSITE_IRAN_VER:=202407080029
|
GEOSITE_IRAN_VER:=202407150030
|
||||||
GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER)
|
GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER)
|
||||||
define Download/geosite-ir
|
define Download/geosite-ir
|
||||||
URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/
|
URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/
|
||||||
URL_FILE:=iran.dat
|
URL_FILE:=iran.dat
|
||||||
FILE:=$(GEOSITE_IRAN_FILE)
|
FILE:=$(GEOSITE_IRAN_FILE)
|
||||||
HASH:=d3c6bd7daab2c720c4c9796c3b31ee7328273cc52b9ff6621e63c5e0513f9a49
|
HASH:=73f55b3bc7ae33c63a9eb5ae11be288d9500b89ffa824584a57eb89cbc84a8d6
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/v2ray-geodata/template
|
define Package/v2ray-geodata/template
|
||||||
|
20
xray-core/.github/workflows/release.yml
vendored
20
xray-core/.github/workflows/release.yml
vendored
@@ -78,6 +78,9 @@ jobs:
|
|||||||
# Include amd64 on all platforms.
|
# Include amd64 on all platforms.
|
||||||
goos: [windows, freebsd, openbsd, linux, darwin]
|
goos: [windows, freebsd, openbsd, linux, darwin]
|
||||||
goarch: [amd64, 386]
|
goarch: [amd64, 386]
|
||||||
|
gotoolchain: [""]
|
||||||
|
patch-assetname: [""]
|
||||||
|
|
||||||
exclude:
|
exclude:
|
||||||
# Exclude i386 on darwin
|
# Exclude i386 on darwin
|
||||||
- goarch: 386
|
- goarch: 386
|
||||||
@@ -152,6 +155,16 @@ jobs:
|
|||||||
goarch: arm
|
goarch: arm
|
||||||
goarm: 7
|
goarm: 7
|
||||||
# END OPENBSD ARM
|
# END OPENBSD ARM
|
||||||
|
# BEGIN Windows 7
|
||||||
|
- goos: windows
|
||||||
|
goarch: amd64
|
||||||
|
gotoolchain: 1.21.4
|
||||||
|
patch-assetname: win7-64
|
||||||
|
- goos: windows
|
||||||
|
goarch: 386
|
||||||
|
gotoolchain: 1.21.4
|
||||||
|
patch-assetname: win7-32
|
||||||
|
# END Windows 7
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -164,16 +177,17 @@ jobs:
|
|||||||
- name: Checkout codebase
|
- name: Checkout codebase
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Show workflow information
|
- name: Show workflow information
|
||||||
run: |
|
run: |
|
||||||
export _NAME=$(jq ".[\"$GOOS-$GOARCH$GOARM$GOMIPS\"].friendlyName" -r < .github/build/friendly-filenames.json)
|
_NAME=${{ matrix.patch-assetname }}
|
||||||
|
[ -n "$_NAME" ] || _NAME=$(jq ".[\"$GOOS-$GOARCH$GOARM$GOMIPS\"].friendlyName" -r < .github/build/friendly-filenames.json)
|
||||||
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME"
|
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME"
|
||||||
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
|
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: go.mod
|
go-version: ${{ matrix.gotoolchain || '1.22' }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Get project dependencies
|
- name: Get project dependencies
|
||||||
|
2
xray-core/.github/workflows/test.yml
vendored
2
xray-core/.github/workflows/test.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: go.mod
|
go-version: '1.22'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore Cache
|
- name: Restore Cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
|
@@ -27,8 +27,7 @@
|
|||||||
- [ghcr.io/xtls/xray-core](https://ghcr.io/xtls/xray-core) (**Official**)
|
- [ghcr.io/xtls/xray-core](https://ghcr.io/xtls/xray-core) (**Official**)
|
||||||
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
|
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
|
||||||
- Web Panel
|
- Web Panel
|
||||||
- [X-UI-English](https://github.com/NidukaAkalanka/x-ui-english), [3X-UI](https://github.com/MHSanaei/3x-ui), [X-UI](https://github.com/alireza0/x-ui), [X-UI](https://github.com/diditra/x-ui)
|
- [3X-UI](https://github.com/MHSanaei/3x-ui), [X-UI](https://github.com/alireza0/x-ui), [Xray-UI](https://github.com/qist/xray-ui)
|
||||||
- [Xray-UI](https://github.com/qist/xray-ui), [X-UI](https://github.com/sing-web/x-ui)
|
|
||||||
- [Hiddify](https://github.com/hiddify/hiddify-config)
|
- [Hiddify](https://github.com/hiddify/hiddify-config)
|
||||||
- [Marzban](https://github.com/Gozargah/Marzban)
|
- [Marzban](https://github.com/Gozargah/Marzban)
|
||||||
- [Libertea](https://github.com/VZiChoushaDui/Libertea)
|
- [Libertea](https://github.com/VZiChoushaDui/Libertea)
|
||||||
@@ -67,13 +66,10 @@
|
|||||||
- [luci-app-xray](https://github.com/yichya/luci-app-xray) ([openwrt-xray](https://github.com/yichya/openwrt-xray))
|
- [luci-app-xray](https://github.com/yichya/luci-app-xray) ([openwrt-xray](https://github.com/yichya/openwrt-xray))
|
||||||
- Windows
|
- Windows
|
||||||
- [v2rayN](https://github.com/2dust/v2rayN)
|
- [v2rayN](https://github.com/2dust/v2rayN)
|
||||||
- [NekoRay](https://github.com/Matsuridayo/nekoray)
|
|
||||||
- [Furious](https://github.com/LorenEteval/Furious)
|
- [Furious](https://github.com/LorenEteval/Furious)
|
||||||
- [HiddifyN](https://github.com/hiddify/HiddifyN)
|
|
||||||
- [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient)
|
- [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient)
|
||||||
- Android
|
- Android
|
||||||
- [v2rayNG](https://github.com/2dust/v2rayNG)
|
- [v2rayNG](https://github.com/2dust/v2rayNG)
|
||||||
- [HiddifyNG](https://github.com/hiddify/HiddifyNG)
|
|
||||||
- [X-flutter](https://github.com/XTLS/X-flutter)
|
- [X-flutter](https://github.com/XTLS/X-flutter)
|
||||||
- iOS & macOS arm64
|
- iOS & macOS arm64
|
||||||
- [FoXray](https://apps.apple.com/app/foxray/id6448898396)
|
- [FoXray](https://apps.apple.com/app/foxray/id6448898396)
|
||||||
@@ -85,7 +81,6 @@
|
|||||||
- [FoXray](https://apps.apple.com/app/foxray/id6448898396)
|
- [FoXray](https://apps.apple.com/app/foxray/id6448898396)
|
||||||
- Linux
|
- Linux
|
||||||
- [v2rayA](https://github.com/v2rayA/v2rayA)
|
- [v2rayA](https://github.com/v2rayA/v2rayA)
|
||||||
- [NekoRay](https://github.com/Matsuridayo/nekoray)
|
|
||||||
- [Furious](https://github.com/LorenEteval/Furious)
|
- [Furious](https://github.com/LorenEteval/Furious)
|
||||||
|
|
||||||
## Others that support VLESS, XTLS, REALITY, XUDP, PLUX...
|
## Others that support VLESS, XTLS, REALITY, XUDP, PLUX...
|
||||||
@@ -98,21 +93,15 @@
|
|||||||
- [XTLS/libXray](https://github.com/XTLS/libXray)
|
- [XTLS/libXray](https://github.com/XTLS/libXray)
|
||||||
- [xtlsapi](https://github.com/hiddify/xtlsapi)
|
- [xtlsapi](https://github.com/hiddify/xtlsapi)
|
||||||
- [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite)
|
- [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite)
|
||||||
- [XrayKit](https://github.com/arror/XrayKit)
|
|
||||||
- [Xray-core-python](https://github.com/LorenEteval/Xray-core-python)
|
- [Xray-core-python](https://github.com/LorenEteval/Xray-core-python)
|
||||||
- [xray-api](https://github.com/XVGuardian/xray-api)
|
- [xray-api](https://github.com/XVGuardian/xray-api)
|
||||||
- [XrayR](https://github.com/XrayR-project/XrayR)
|
- [XrayR](https://github.com/XrayR-project/XrayR)
|
||||||
- [XrayR-release](https://github.com/XrayR-project/XrayR-release)
|
- [XrayR-release](https://github.com/XrayR-project/XrayR-release)
|
||||||
- [XrayR-V2Board](https://github.com/missuo/XrayR-V2Board)
|
- [XrayR-V2Board](https://github.com/missuo/XrayR-V2Board)
|
||||||
- [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
- [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
||||||
- [Clash Verge](https://github.com/zzzgydi/clash-verge)
|
|
||||||
- [clashN](https://github.com/2dust/clashN)
|
- [clashN](https://github.com/2dust/clashN)
|
||||||
- [Clash Meta for Android](https://github.com/MetaCubeX/ClashMetaForAndroid)
|
- [Clash Meta for Android](https://github.com/MetaCubeX/ClashMetaForAndroid)
|
||||||
- [meta_for_ios](https://t.me/meta_for_ios)
|
|
||||||
- [sing-box](https://github.com/SagerNet/sing-box)
|
- [sing-box](https://github.com/SagerNet/sing-box)
|
||||||
- [installReality](https://github.com/BoxXt/installReality)
|
|
||||||
- [sbox-reality](https://github.com/Misaka-blog/sbox-reality)
|
|
||||||
- [sing-box-for-ios](https://github.com/SagerNet/sing-box-for-ios)
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@@ -151,7 +151,7 @@ func LogInfo(ctx context.Context, msg ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LogInfoInner(ctx context.Context, inner error, msg ...interface{}) {
|
func LogInfoInner(ctx context.Context, inner error, msg ...interface{}) {
|
||||||
doLog(ctx, inner, log.Severity_Debug, msg...)
|
doLog(ctx, inner, log.Severity_Info, msg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogWarning(ctx context.Context, msg ...interface{}) {
|
func LogWarning(ctx context.Context, msg ...interface{}) {
|
||||||
@@ -159,7 +159,7 @@ func LogWarning(ctx context.Context, msg ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LogWarningInner(ctx context.Context, inner error, msg ...interface{}) {
|
func LogWarningInner(ctx context.Context, inner error, msg ...interface{}) {
|
||||||
doLog(ctx, inner, log.Severity_Debug, msg...)
|
doLog(ctx, inner, log.Severity_Warning, msg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogError(ctx context.Context, msg ...interface{}) {
|
func LogError(ctx context.Context, msg ...interface{}) {
|
||||||
@@ -167,7 +167,7 @@ func LogError(ctx context.Context, msg ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LogErrorInner(ctx context.Context, inner error, msg ...interface{}) {
|
func LogErrorInner(ctx context.Context, inner error, msg ...interface{}) {
|
||||||
doLog(ctx, inner, log.Severity_Debug, msg...)
|
doLog(ctx, inner, log.Severity_Error, msg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func doLog(ctx context.Context, inner error, severity log.Severity, msg ...interface{}) {
|
func doLog(ctx context.Context, inner error, severity log.Severity, msg ...interface{}) {
|
||||||
|
@@ -21,7 +21,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
Version_x byte = 1
|
Version_x byte = 1
|
||||||
Version_y byte = 8
|
Version_y byte = 8
|
||||||
Version_z byte = 17
|
Version_z byte = 18
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
module github.com/xtls/xray-core
|
module github.com/xtls/xray-core
|
||||||
|
|
||||||
go 1.22
|
go 1.21.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0
|
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0
|
||||||
|
@@ -17,7 +17,7 @@ More details are at [Latest Release Page](https://github.com/Chilledheart/yass/r
|
|||||||
- GTK3 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk3.el8.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk3-ubuntu-16.04-xenial_amd64.1.11.4.deb) (minimum requirement: centos 8 or ubuntu 16.04)
|
- GTK3 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk3.el8.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk3-ubuntu-16.04-xenial_amd64.1.11.4.deb) (minimum requirement: centos 8 or ubuntu 16.04)
|
||||||
- Qt5 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt5.el8.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt5-ubuntu-16.04-xenial_amd64.1.11.4.deb) (minimum requirement: centos 8 or ubuntu 16.04)
|
- Qt5 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt5.el8.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt5-ubuntu-16.04-xenial_amd64.1.11.4.deb) (minimum requirement: centos 8 or ubuntu 16.04)
|
||||||
- GTK4 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk4.lp155.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk4-ubuntu-22.04-jammy_amd64.1.11.4.deb) (minimum requirement: opensuse leap 15.5, centos 9 or ubuntu 22.04)
|
- GTK4 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk4.lp155.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-gtk4-ubuntu-22.04-jammy_amd64.1.11.4.deb) (minimum requirement: opensuse leap 15.5, centos 9 or ubuntu 22.04)
|
||||||
- Qt6 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt6.lp155.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt6-ubuntu-22.04-jammy_amd64.1.11.4.deb) (minimum requirement: opensuse leap 15.5 or ubuntu 22.04)
|
- Qt6 [download rpm](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt6.lp155.x86_64.1.11.4.rpm) or [download deb](https://github.com/Chilledheart/yass/releases/download/1.11.4/yass-qt6-ubuntu-22.04-jammy_amd64.1.11.4.deb) (minimum requirement: opensuse leap 15.5, centos 9 with epel or ubuntu 22.04)
|
||||||
|
|
||||||
[](https://aur.archlinux.org/packages/yass-proxy-gtk3)
|
[](https://aur.archlinux.org/packages/yass-proxy-gtk3)
|
||||||
[](https://aur.archlinux.org/packages/yass-proxy-qt5)
|
[](https://aur.archlinux.org/packages/yass-proxy-qt5)
|
||||||
|
@@ -1859,6 +1859,9 @@ The following extractors use this feature:
|
|||||||
#### bilibili
|
#### bilibili
|
||||||
* `prefer_multi_flv`: Prefer extracting flv formats over mp4 for older videos that still provide legacy formats
|
* `prefer_multi_flv`: Prefer extracting flv formats over mp4 for older videos that still provide legacy formats
|
||||||
|
|
||||||
|
#### digitalconcerthall
|
||||||
|
* `prefer_combined_hls`: Prefer extracting combined/pre-merged video and audio HLS formats. This will exclude 4K/HEVC video and lossless/FLAC audio formats, which are only available as split video/audio HLS formats
|
||||||
|
|
||||||
**Note**: These options may be changed/removed in the future without concern for backward compatibility
|
**Note**: These options may be changed/removed in the future without concern for backward compatibility
|
||||||
|
|
||||||
<!-- MANPAGE: MOVE "INSTALLATION" SECTION HERE -->
|
<!-- MANPAGE: MOVE "INSTALLATION" SECTION HERE -->
|
||||||
|
@@ -929,6 +929,11 @@ class TestUtil(unittest.TestCase):
|
|||||||
'acodec': 'none',
|
'acodec': 'none',
|
||||||
'dynamic_range': 'DV',
|
'dynamic_range': 'DV',
|
||||||
})
|
})
|
||||||
|
self.assertEqual(parse_codecs('fLaC'), {
|
||||||
|
'vcodec': 'none',
|
||||||
|
'acodec': 'flac',
|
||||||
|
'dynamic_range': None,
|
||||||
|
})
|
||||||
self.assertEqual(parse_codecs('theora, vorbis'), {
|
self.assertEqual(parse_codecs('theora, vorbis'), {
|
||||||
'vcodec': 'theora',
|
'vcodec': 'theora',
|
||||||
'acodec': 'vorbis',
|
'acodec': 'vorbis',
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
|
from ..networking.exceptions import HTTPError
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
|
parse_codecs,
|
||||||
try_get,
|
try_get,
|
||||||
url_or_none,
|
url_or_none,
|
||||||
urlencode_postdata,
|
urlencode_postdata,
|
||||||
@@ -12,6 +14,7 @@ class DigitalConcertHallIE(InfoExtractor):
|
|||||||
IE_DESC = 'DigitalConcertHall extractor'
|
IE_DESC = 'DigitalConcertHall extractor'
|
||||||
_VALID_URL = r'https?://(?:www\.)?digitalconcerthall\.com/(?P<language>[a-z]+)/(?P<type>film|concert|work)/(?P<id>[0-9]+)-?(?P<part>[0-9]+)?'
|
_VALID_URL = r'https?://(?:www\.)?digitalconcerthall\.com/(?P<language>[a-z]+)/(?P<type>film|concert|work)/(?P<id>[0-9]+)-?(?P<part>[0-9]+)?'
|
||||||
_OAUTH_URL = 'https://api.digitalconcerthall.com/v2/oauth2/token'
|
_OAUTH_URL = 'https://api.digitalconcerthall.com/v2/oauth2/token'
|
||||||
|
_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15'
|
||||||
_ACCESS_TOKEN = None
|
_ACCESS_TOKEN = None
|
||||||
_NETRC_MACHINE = 'digitalconcerthall'
|
_NETRC_MACHINE = 'digitalconcerthall'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
@@ -68,33 +71,42 @@ class DigitalConcertHallIE(InfoExtractor):
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
def _perform_login(self, username, password):
|
def _perform_login(self, username, password):
|
||||||
token_response = self._download_json(
|
login_token = self._download_json(
|
||||||
self._OAUTH_URL,
|
self._OAUTH_URL,
|
||||||
None, 'Obtaining token', errnote='Unable to obtain token', data=urlencode_postdata({
|
None, 'Obtaining token', errnote='Unable to obtain token', data=urlencode_postdata({
|
||||||
'affiliate': 'none',
|
'affiliate': 'none',
|
||||||
'grant_type': 'device',
|
'grant_type': 'device',
|
||||||
'device_vendor': 'unknown',
|
'device_vendor': 'unknown',
|
||||||
|
# device_model 'Safari' gets split streams of 4K/HEVC video and lossless/FLAC audio
|
||||||
|
'device_model': 'unknown' if self._configuration_arg('prefer_combined_hls') else 'Safari',
|
||||||
'app_id': 'dch.webapp',
|
'app_id': 'dch.webapp',
|
||||||
'app_version': '1.0.0',
|
'app_distributor': 'berlinphil',
|
||||||
|
'app_version': '1.84.0',
|
||||||
'client_secret': '2ySLN+2Fwb',
|
'client_secret': '2ySLN+2Fwb',
|
||||||
}), headers={
|
}), headers={
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
'Accept': 'application/json',
|
||||||
})
|
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
||||||
self._ACCESS_TOKEN = token_response['access_token']
|
'User-Agent': self._USER_AGENT,
|
||||||
|
})['access_token']
|
||||||
try:
|
try:
|
||||||
self._download_json(
|
login_response = self._download_json(
|
||||||
self._OAUTH_URL,
|
self._OAUTH_URL,
|
||||||
None, note='Logging in', errnote='Unable to login', data=urlencode_postdata({
|
None, note='Logging in', errnote='Unable to login', data=urlencode_postdata({
|
||||||
'grant_type': 'password',
|
'grant_type': 'password',
|
||||||
'username': username,
|
'username': username,
|
||||||
'password': password,
|
'password': password,
|
||||||
}), headers={
|
}), headers={
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
||||||
'Referer': 'https://www.digitalconcerthall.com',
|
'Referer': 'https://www.digitalconcerthall.com',
|
||||||
'Authorization': f'Bearer {self._ACCESS_TOKEN}',
|
'Authorization': f'Bearer {login_token}',
|
||||||
|
'User-Agent': self._USER_AGENT,
|
||||||
})
|
})
|
||||||
except ExtractorError:
|
except ExtractorError as error:
|
||||||
self.raise_login_required(msg='Login info incorrect')
|
if isinstance(error.cause, HTTPError) and error.cause.status == 401:
|
||||||
|
raise ExtractorError('Invalid username or password', expected=True)
|
||||||
|
raise
|
||||||
|
self._ACCESS_TOKEN = login_response['access_token']
|
||||||
|
|
||||||
def _real_initialize(self):
|
def _real_initialize(self):
|
||||||
if not self._ACCESS_TOKEN:
|
if not self._ACCESS_TOKEN:
|
||||||
@@ -108,11 +120,15 @@ class DigitalConcertHallIE(InfoExtractor):
|
|||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': f'Bearer {self._ACCESS_TOKEN}',
|
'Authorization': f'Bearer {self._ACCESS_TOKEN}',
|
||||||
'Accept-Language': language,
|
'Accept-Language': language,
|
||||||
|
'User-Agent': self._USER_AGENT,
|
||||||
})
|
})
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
for m3u8_url in traverse_obj(stream_info, ('channel', ..., 'stream', ..., 'url', {url_or_none})):
|
for m3u8_url in traverse_obj(stream_info, ('channel', ..., 'stream', ..., 'url', {url_or_none})):
|
||||||
formats.extend(self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', fatal=False))
|
formats.extend(self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', m3u8_id='hls', fatal=False))
|
||||||
|
for fmt in formats:
|
||||||
|
if fmt.get('format_note') and fmt.get('vcodec') == 'none':
|
||||||
|
fmt.update(parse_codecs(fmt['format_note']))
|
||||||
|
|
||||||
yield {
|
yield {
|
||||||
'id': video_id,
|
'id': video_id,
|
||||||
@@ -140,13 +156,15 @@ class DigitalConcertHallIE(InfoExtractor):
|
|||||||
f'https://api.digitalconcerthall.com/v2/{api_type}/{video_id}', video_id, headers={
|
f'https://api.digitalconcerthall.com/v2/{api_type}/{video_id}', video_id, headers={
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Accept-Language': language,
|
'Accept-Language': language,
|
||||||
|
'User-Agent': self._USER_AGENT,
|
||||||
|
'Authorization': f'Bearer {self._ACCESS_TOKEN}',
|
||||||
})
|
})
|
||||||
album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name'))
|
|
||||||
videos = [vid_info] if type_ == 'film' else traverse_obj(vid_info, ('_embedded', ..., ...))
|
videos = [vid_info] if type_ == 'film' else traverse_obj(vid_info, ('_embedded', ..., ...))
|
||||||
|
|
||||||
if type_ == 'work':
|
if type_ == 'work':
|
||||||
videos = [videos[int(part) - 1]]
|
videos = [videos[int(part) - 1]]
|
||||||
|
|
||||||
|
album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name', {str}))
|
||||||
thumbnail = traverse_obj(vid_info, (
|
thumbnail = traverse_obj(vid_info, (
|
||||||
'image', ..., {self._proto_relative_url}, {url_or_none},
|
'image', ..., {self._proto_relative_url}, {url_or_none},
|
||||||
{lambda x: x.format(width=0, height=0)}, any)) # NB: 0x0 is the original size
|
{lambda x: x.format(width=0, height=0)}, any)) # NB: 0x0 is the original size
|
||||||
|
@@ -43,6 +43,7 @@ from ..utils import (
|
|||||||
xpath_text,
|
xpath_text,
|
||||||
xpath_with_ns,
|
xpath_with_ns,
|
||||||
)
|
)
|
||||||
|
from ..utils._utils import _UnsafeExtensionError
|
||||||
|
|
||||||
|
|
||||||
class GenericIE(InfoExtractor):
|
class GenericIE(InfoExtractor):
|
||||||
@@ -2446,9 +2447,13 @@ class GenericIE(InfoExtractor):
|
|||||||
if not is_html(first_bytes):
|
if not is_html(first_bytes):
|
||||||
self.report_warning(
|
self.report_warning(
|
||||||
'URL could be a direct video link, returning it as such.')
|
'URL could be a direct video link, returning it as such.')
|
||||||
|
ext = determine_ext(url)
|
||||||
|
if ext not in _UnsafeExtensionError.ALLOWED_EXTENSIONS:
|
||||||
|
ext = 'unknown_video'
|
||||||
info_dict.update({
|
info_dict.update({
|
||||||
'direct': True,
|
'direct': True,
|
||||||
'url': url,
|
'url': url,
|
||||||
|
'ext': ext,
|
||||||
})
|
})
|
||||||
return info_dict
|
return info_dict
|
||||||
|
|
||||||
|
@@ -871,7 +871,7 @@ class SoundcloudUserPermalinkIE(SoundcloudPagedPlaylistBaseIE):
|
|||||||
'id': '30909869',
|
'id': '30909869',
|
||||||
'title': 'neilcic',
|
'title': 'neilcic',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 23,
|
'playlist_mincount': 22,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
@@ -880,7 +880,7 @@ class SoundcloudUserPermalinkIE(SoundcloudPagedPlaylistBaseIE):
|
|||||||
self._resolv_url(url), user_id, 'Downloading user info', headers=self._HEADERS)
|
self._resolv_url(url), user_id, 'Downloading user info', headers=self._HEADERS)
|
||||||
|
|
||||||
return self._extract_playlist(
|
return self._extract_playlist(
|
||||||
f'{self._API_V2_BASE}stream/users/{user["id"]}', str(user['id']), user.get('username'))
|
f'{self._API_V2_BASE}users/{user["id"]}/tracks', str(user['id']), user.get('username'))
|
||||||
|
|
||||||
|
|
||||||
class SoundcloudTrackStationIE(SoundcloudPagedPlaylistBaseIE):
|
class SoundcloudTrackStationIE(SoundcloudPagedPlaylistBaseIE):
|
||||||
|
@@ -270,7 +270,7 @@ def build_innertube_clients():
|
|||||||
THIRD_PARTY = {
|
THIRD_PARTY = {
|
||||||
'embedUrl': 'https://www.youtube.com/', # Can be any valid URL
|
'embedUrl': 'https://www.youtube.com/', # Can be any valid URL
|
||||||
}
|
}
|
||||||
BASE_CLIENTS = ('ios', 'android', 'web', 'tv', 'mweb')
|
BASE_CLIENTS = ('ios', 'web', 'tv', 'mweb', 'android')
|
||||||
priority = qualities(BASE_CLIENTS[::-1])
|
priority = qualities(BASE_CLIENTS[::-1])
|
||||||
|
|
||||||
for client, ytcfg in tuple(INNERTUBE_CLIENTS.items()):
|
for client, ytcfg in tuple(INNERTUBE_CLIENTS.items()):
|
||||||
@@ -3702,17 +3702,17 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
return pr_id
|
return pr_id
|
||||||
|
|
||||||
def _extract_player_responses(self, clients, video_id, webpage, master_ytcfg, smuggled_data):
|
def _extract_player_responses(self, clients, video_id, webpage, master_ytcfg, smuggled_data):
|
||||||
initial_pr = None
|
initial_pr = ignore_initial_response = None
|
||||||
if webpage:
|
if webpage:
|
||||||
experiments = traverse_obj(master_ytcfg, (
|
if 'web' in clients:
|
||||||
'WEB_PLAYER_CONTEXT_CONFIGS', ..., 'serializedExperimentIds', {str}, {lambda x: x.split(',')}, ..., {str}))
|
experiments = traverse_obj(master_ytcfg, (
|
||||||
if all(x in experiments for x in self._POTOKEN_EXPERIMENTS):
|
'WEB_PLAYER_CONTEXT_CONFIGS', ..., 'serializedExperimentIds', {lambda x: x.split(',')}, ...))
|
||||||
self.report_warning(
|
if all(x in experiments for x in self._POTOKEN_EXPERIMENTS):
|
||||||
'Webpage contains broken formats (poToken experiment detected). Ignoring initial player response')
|
self.report_warning(
|
||||||
master_ytcfg = self._get_default_ytcfg()
|
'Webpage contains broken formats (poToken experiment detected). Ignoring initial player response')
|
||||||
else:
|
ignore_initial_response = True
|
||||||
initial_pr = self._search_json(
|
initial_pr = self._search_json(
|
||||||
self._YT_INITIAL_PLAYER_RESPONSE_RE, webpage, 'initial player response', video_id, fatal=False)
|
self._YT_INITIAL_PLAYER_RESPONSE_RE, webpage, 'initial player response', video_id, fatal=False)
|
||||||
|
|
||||||
prs = []
|
prs = []
|
||||||
if initial_pr and not self._invalid_player_response(initial_pr, video_id):
|
if initial_pr and not self._invalid_player_response(initial_pr, video_id):
|
||||||
@@ -3740,8 +3740,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
skipped_clients = {}
|
skipped_clients = {}
|
||||||
while clients:
|
while clients:
|
||||||
client, base_client, variant = _split_innertube_client(clients.pop())
|
client, base_client, variant = _split_innertube_client(clients.pop())
|
||||||
player_ytcfg = master_ytcfg if client == 'web' else {}
|
player_ytcfg = {}
|
||||||
if 'configs' not in self._configuration_arg('player_skip') and client != 'web':
|
if client == 'web':
|
||||||
|
player_ytcfg = self._get_default_ytcfg() if ignore_initial_response else master_ytcfg
|
||||||
|
elif 'configs' not in self._configuration_arg('player_skip'):
|
||||||
player_ytcfg = self._download_ytcfg(client, video_id) or player_ytcfg
|
player_ytcfg = self._download_ytcfg(client, video_id) or player_ytcfg
|
||||||
|
|
||||||
player_url = player_url or self._extract_player_url(master_ytcfg, player_ytcfg, webpage=webpage)
|
player_url = player_url or self._extract_player_url(master_ytcfg, player_ytcfg, webpage=webpage)
|
||||||
@@ -3754,7 +3756,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
player_url = self._download_player_url(video_id)
|
player_url = self._download_player_url(video_id)
|
||||||
tried_iframe_fallback = True
|
tried_iframe_fallback = True
|
||||||
|
|
||||||
pr = initial_pr if client == 'web' and initial_pr else None
|
pr = initial_pr if client == 'web' and not ignore_initial_response else None
|
||||||
for retry in self.RetryManager(fatal=False):
|
for retry in self.RetryManager(fatal=False):
|
||||||
try:
|
try:
|
||||||
pr = pr or self._extract_player_response(
|
pr = pr or self._extract_player_response(
|
||||||
@@ -3765,7 +3767,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
break
|
break
|
||||||
experiments = traverse_obj(pr, (
|
experiments = traverse_obj(pr, (
|
||||||
'responseContext', 'serviceTrackingParams', lambda _, v: v['service'] == 'GFEEDBACK',
|
'responseContext', 'serviceTrackingParams', lambda _, v: v['service'] == 'GFEEDBACK',
|
||||||
'params', lambda _, v: v['key'] == 'e', 'value', {lambda x: x.split(',')}, ..., {str}))
|
'params', lambda _, v: v['key'] == 'e', 'value', {lambda x: x.split(',')}, ...))
|
||||||
if all(x in experiments for x in self._POTOKEN_EXPERIMENTS):
|
if all(x in experiments for x in self._POTOKEN_EXPERIMENTS):
|
||||||
pr = None
|
pr = None
|
||||||
retry.error = ExtractorError('API returned broken formats (poToken experiment detected)', expected=True)
|
retry.error = ExtractorError('API returned broken formats (poToken experiment detected)', expected=True)
|
||||||
|
@@ -2984,6 +2984,7 @@ def parse_codecs(codecs_str):
|
|||||||
str.strip, codecs_str.strip().strip(',').split(','))))
|
str.strip, codecs_str.strip().strip(',').split(','))))
|
||||||
vcodec, acodec, scodec, hdr = None, None, None, None
|
vcodec, acodec, scodec, hdr = None, None, None, None
|
||||||
for full_codec in split_codecs:
|
for full_codec in split_codecs:
|
||||||
|
full_codec = re.sub(r'^([^.]+)', lambda m: m.group(1).lower(), full_codec)
|
||||||
parts = re.sub(r'0+(?=\d)', '', full_codec).split('.')
|
parts = re.sub(r'0+(?=\d)', '', full_codec).split('.')
|
||||||
if parts[0] in ('avc1', 'avc2', 'avc3', 'avc4', 'vp9', 'vp8', 'hev1', 'hev2',
|
if parts[0] in ('avc1', 'avc2', 'avc3', 'avc4', 'vp9', 'vp8', 'hev1', 'hev2',
|
||||||
'h263', 'h264', 'mp4v', 'hvc1', 'av1', 'theora', 'dvh1', 'dvhe'):
|
'h263', 'h264', 'mp4v', 'hvc1', 'av1', 'theora', 'dvh1', 'dvhe'):
|
||||||
|
Reference in New Issue
Block a user