Update On Mon Jul 15 20:32:26 CEST 2024

This commit is contained in:
github-action[bot]
2024-07-15 20:32:26 +02:00
parent 5375a8745d
commit bdc5abca14
57 changed files with 1214 additions and 1210 deletions

1
.github/update.log vendored
View File

@@ -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 Sat Jul 13 20:28:46 CEST 2024
Update On Sun Jul 14 20:40:18 CEST 2024
Update On Mon Jul 15 20:32:15 CEST 2024

View File

@@ -69,7 +69,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
}
if groupOption.IncludeAllProviders {
groupOption.Use = append(groupOption.Use, AllProviders...)
groupOption.Use = AllProviders
}
if groupOption.IncludeAllProxies {
if groupOption.Filter != "" {

View File

@@ -1779,9 +1779,9 @@ dependencies = [
[[package]]
name = "fast_image_resize"
version = "4.0.0"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02abb58c39fa9b20678cedabab49e6c4f6ecb7480d7cb5711496b9289184a875"
checksum = "89a06940fe3bab6e93dc275bb8a67cc833b70f4078124e7e7f7352f5c8470e63"
dependencies = [
"cfg-if",
"document-features",

View File

@@ -108,7 +108,7 @@
},
"windows": [],
"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:;"
}
}
}

View File

@@ -258,12 +258,23 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
submit-to-winget:
runs-on: windows-latest
runs-on: ubuntu-latest
needs: [release-update]
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
uses: vedantmgoyal9/winget-releaser@main
with:
identifier: ClashVergeRev.ClashVergeRev
version: ${{env.VERSION}}
release-tag: v${{env.VERSION}}
installers-regex: '_(arm64|x64|x86)-setup\.exe$'
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.WINGET_TOKEN }}

View File

@@ -1,3 +1,28 @@
## v1.7.5
### Features
- 展示局域网 IP 地址信息
- 在设置页面直接复制环境变量
- 优化服务模式安装逻辑
### Performance
- 优化切换订阅速度
- 优化更改端口速度
### Bugs Fixes
- 调整 MacOS 托盘图标大小
- Trojan URI 解析错误
- 卡片拖动显示层级错误
- 代理绕过格式检查错误
- MacOS 下编辑器最大化失败
- MacOS 服务安装失败
- 更改窗口大小导致闪退的问题
---
## v1.7.3
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "clash-verge",
"version": "1.7.3",
"version": "1.7.5",
"license": "GPL-3.0-only",
"scripts": {
"dev": "tauri dev",

View File

@@ -790,7 +790,7 @@ dependencies = [
[[package]]
name = "clash-verge"
version = "1.7.3"
version = "1.7.5"
dependencies = [
"anyhow",
"auto-launch",

View File

@@ -1,6 +1,6 @@
[package]
name = "clash-verge"
version = "1.7.3"
version = "1.7.5"
description = "clash verge"
authors = ["zzzgydi", "wonfen", "MystiPanda"]
license = "GPL-3.0-only"

View File

@@ -191,11 +191,15 @@ pub fn init_config() -> Result<()> {
/// after tauri setup
pub fn init_resources() -> Result<()> {
let app_dir = dirs::app_home_dir()?;
let test_dir = app_dir.join("test");
let res_dir = dirs::app_resources_dir()?;
if !app_dir.exists() {
let _ = fs::create_dir_all(&app_dir);
}
if !test_dir.exists() {
let _ = fs::create_dir_all(&test_dir);
}
if !res_dir.exists() {
let _ = fs::create_dir_all(&res_dir);
}
@@ -210,9 +214,10 @@ pub fn init_resources() -> Result<()> {
for file in file_list.iter() {
let src_path = res_dir.join(file);
let dest_path = app_dir.join(file);
let test_dest_path = test_dir.join(file);
let handle_copy = || {
match fs::copy(&src_path, &dest_path) {
let handle_copy = |dest: &PathBuf| {
match fs::copy(&src_path, dest) {
Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
Err(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() {
handle_copy();
handle_copy(&dest_path);
continue;
}
@@ -231,14 +239,14 @@ pub fn init_resources() -> Result<()> {
match (src_modified, dest_modified) {
(Ok(src_modified), Ok(dest_modified)) => {
if src_modified > dest_modified {
handle_copy();
handle_copy(&dest_path);
} else {
log::debug!(target: "app", "skipping resource copy '{file}'");
}
}
_ => {
log::debug!(target: "app", "failed to get modified '{file}'");
handle_copy();
handle_copy(&dest_path);
}
};
}

View File

@@ -2,7 +2,7 @@
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"package": {
"productName": "Clash Verge",
"version": "1.7.3"
"version": "1.7.5"
},
"build": {
"distDir": "../dist",

View File

@@ -11,6 +11,7 @@ export const Switch = styled((props: SwitchProps) => (
width: 42,
height: 26,
padding: 0,
marginRight: 1,
"& .MuiSwitch-switchBase": {
padding: 0,
margin: 2,

View File

@@ -49,9 +49,8 @@ export const NetworkInterfaceViewer = forwardRef<DialogRef>((props, ref) => {
</Box>
}
contentSx={{ width: 450, maxHeight: 330 }}
okBtn={t("Save")}
cancelBtn={t("Cancel")}
onClose={() => setOpen(false)}
disableOk
cancelBtn={t("Close")}
onCancel={() => setOpen(false)}
>
{networkInterfaces.map((item) => (

View File

@@ -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>
)}
</>
);
};

View File

@@ -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>
);
});

View File

@@ -1,13 +1,13 @@
import useSWR from "swr";
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import { PrivacyTipRounded, SettingsRounded } from "@mui/icons-material";
import { SettingsRounded } from "@mui/icons-material";
import { checkService } from "@/services/cmds";
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 { GuardState } from "./mods/guard-state";
import { ServiceViewer } from "./mods/service-viewer";
import { ServiceSwitcher } from "./mods/service-switcher";
import { SysproxyViewer } from "./mods/sysproxy-viewer";
import { TunViewer } from "./mods/tun-viewer";
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
@@ -20,22 +20,23 @@ const SettingSystem = ({ onError }: Props) => {
const { t } = useTranslation();
const { verge, mutateVerge, patchVerge } = useVerge();
// service mode
const { data: serviceStatus } = useSWR("checkService", checkService, {
const { data: serviceStatus, mutate: mutateServiceStatus } = useSWR(
"checkService",
checkService,
{
revalidateIfStale: false,
shouldRetryOnError: false,
focusThrottleInterval: 36e5, // 1 hour
});
}
);
const serviceRef = useRef<DialogRef>(null);
const sysproxyRef = useRef<DialogRef>(null);
const tunRef = useRef<DialogRef>(null);
const {
enable_tun_mode,
enable_auto_launch,
enable_service_mode,
enable_silent_start,
enable_system_proxy,
} = verge ?? {};
@@ -49,7 +50,6 @@ const SettingSystem = ({ onError }: Props) => {
<SettingList title={t("System Setting")}>
<SysproxyViewer ref={sysproxyRef} />
<TunViewer ref={tunRef} />
<ServiceViewer ref={serviceRef} enable={!!enable_service_mode} />
<SettingItem
label={t("Tun Mode")}
@@ -66,38 +66,33 @@ const SettingSystem = ({ onError }: Props) => {
valueProps="checked"
onCatch={onError}
onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ enable_tun_mode: e })}
onGuard={(e) => patchVerge({ enable_tun_mode: e })}
onChange={(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" />
</GuardState>
</SettingItem>
<SettingItem
label={t("Service Mode")}
extra={
<TooltipIcon
title={t("Service Mode Info")}
icon={PrivacyTipRounded}
onClick={() => serviceRef.current?.open()}
<SettingItem label={t("Service Mode")}>
<ServiceSwitcher
status={serviceStatus ?? "unknown"}
mutate={mutateServiceStatus}
patchVerge={patchVerge}
onChangeData={onChangeData}
/>
}
>
<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

View File

@@ -266,7 +266,7 @@
"Restart": "Restart",
"Release Version": "Release Version",
"Alpha Version": "Alpha Version",
"Tun mode requires": "Tun mode requires",
"Please Enable Service Mode": "Please Install and Enable Service Mode First",
"Grant": "Grant",
"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",

View File

@@ -261,7 +261,7 @@
"Restart": "راه‌اندازی مجدد",
"Release Version": "نسخه نهایی",
"Alpha Version": "نسخه آلفا",
"Tun mode requires": "Tun mode نیاز دارد",
"Please Install and Enable Service Mode First": "لطفاً ابتدا حالت سرویس را نصب و فعال کنید",
"Grant": "اعطا",
"Open UWP tool": "باز کردن ابزار UWP",
"Open UWP tool Info": "از ویندوز 8 به بعد، برنامه‌های UWP (مانند Microsoft Store) از دسترسی مستقیم به خدمات شبکه محلی محدود شده‌اند و این ابزار می‌تواند برای دور زدن این محدودیت استفاده شود",

View File

@@ -264,7 +264,7 @@
"Restart": "Перезапуск",
"Release Version": "Официальная версия",
"Alpha Version": "Альфа-версия",
"Tun mode requires": "Требуется Режим туннеля",
"Please Enable Service Mode": "Пожалуйста, сначала установите и включите режим обслуживания",
"Grant": "Предоставить",
"Open UWP tool": "Открыть UWP инструмент",
"Open UWP tool Info": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение",

View File

@@ -266,7 +266,7 @@
"Restart": "重启内核",
"Release Version": "正式版",
"Alpha Version": "预览版",
"Tun mode requires": "如需启用 Tun 模式需要授权",
"Please Enable Service Mode": "请先安装并启用服务模式",
"Grant": "授权",
"Open UWP tool": "UWP 工具",
"Open UWP tool Info": "Windows 8开始限制 UWP 应用(如微软商店)直接访问本地主机的网络服务,使用此工具可绕过该限制",

View File

@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=lua
PKG_VERSION:=5.1.5
PKG_RELEASE:=10
PKG_RELEASE:=11
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lua.org/ftp/ \

View File

@@ -8,7 +8,6 @@ Including it allows multiple lua versions to coexist.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -41,10 +41,10 @@ RANLIB= ranlib
@@ -42,7 +41,7 @@ rename to doc/luac5.1.1
diff --git a/src/Makefile b/src/Makefile
--- a/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 \
lstrlib.o loadlib.o linit.o

View File

@@ -1,8 +1,6 @@
diff --git a/src/lnum.c b/src/lnum.c
index 1456b6a2ed23..b0632b04c2b7 100644
--- a/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
return 0; /* Reject the number */
#endif
@@ -11,7 +9,7 @@ index 1456b6a2ed23..b0632b04c2b7 100644
}
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
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;
}
@@ -25,8 +23,6 @@ index 1456b6a2ed23..b0632b04c2b7 100644
+ return (unsigned LUA_INTEGER)v;
+}
+#endif
diff --git a/src/lnum_config.h b/src/lnum_config.h
index 19d7a4231a49..1092eead6629 100644
--- a/src/lnum_config.h
+++ b/src/lnum_config.h
@@ -141,7 +141,12 @@
@@ -43,6 +39,3 @@ index 19d7a4231a49..1092eead6629 100644
#endif
#ifndef LUA_INTEGER_MIN
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
--
1.9.1

View File

@@ -10,7 +10,7 @@
#if defined(LUA_USE_MACOSX)
--- a/src/Makefile
+++ b/src/Makefile
@@ -17,6 +17,7 @@
@@ -17,6 +17,7 @@ LIBS= -lm $(MYLIBS)
MYCFLAGS=
MYLDFLAGS=
MYLIBS=
@@ -18,7 +18,7 @@
# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
@@ -75,7 +76,7 @@
@@ -75,7 +76,7 @@ echo:
@echo "MYLIBS = $(MYLIBS)"
# convenience targets for popular platforms
@@ -27,7 +27,7 @@
none:
@echo "Please choose a platform:"
@echo " $(PLATS)"
@@ -90,16 +91,16 @@
@@ -90,16 +91,16 @@ bsd:
$(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
freebsd:

View 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;

View File

@@ -8,7 +8,6 @@ Including it allows multiple lua versions to coexist.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -41,10 +41,10 @@ RANLIB= ranlib
@@ -42,7 +41,7 @@ rename to doc/luac5.1.1
diff --git a/src/Makefile b/src/Makefile
--- a/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 \
lstrlib.o loadlib.o linit.o

View File

@@ -1,8 +1,6 @@
diff --git a/src/lnum.c b/src/lnum.c
index 1456b6a2ed23..b0632b04c2b7 100644
--- a/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
return 0; /* Reject the number */
#endif
@@ -11,7 +9,7 @@ index 1456b6a2ed23..b0632b04c2b7 100644
}
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
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;
}
@@ -25,8 +23,6 @@ index 1456b6a2ed23..b0632b04c2b7 100644
+ return (unsigned LUA_INTEGER)v;
+}
+#endif
diff --git a/src/lnum_config.h b/src/lnum_config.h
index 19d7a4231a49..1092eead6629 100644
--- a/src/lnum_config.h
+++ b/src/lnum_config.h
@@ -141,7 +141,12 @@
@@ -43,6 +39,3 @@ index 19d7a4231a49..1092eead6629 100644
#endif
#ifndef LUA_INTEGER_MIN
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
--
1.9.1

View 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;

View File

@@ -88,10 +88,10 @@ type BBRSender struct {
currentRoundTripEnd int64
// 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.
maxAckHeight WindowedFilter[uint64]
maxAckHeight WindowedFilter[int64]
// The time this aggregation started and the number of bytes acked during it.
aggregationEpochStartTime time.Time
@@ -158,7 +158,7 @@ type BBRSender struct {
isAtFullBandwidth bool
// Number of rounds during which there was no significant bandwidth increase.
roundsWithoutBandwidthGain uint64
roundsWithoutBandwidthGain int64
// The bandwidth compared to which the increase is measured.
bandwidthAtLastRound int64
@@ -234,7 +234,7 @@ func (b *BBRSender) IsProbingForMoreBandwidth() bool {
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 {
b.maxBandwidth.Update(bandwidth, b.roundTripCount)
}
@@ -276,8 +276,7 @@ func (b *BBRSender) PacingRate(bytesInFlight int64) int64 {
}
func (b *BBRSender) BandwidthEstimate() int64 {
// Implementation here
return 0
return b.maxBandwidth.GetBest()
}
func (b *BBRSender) GetCongestionWindow() int64 {
@@ -286,7 +285,6 @@ func (b *BBRSender) GetCongestionWindow() int64 {
}
func (b *BBRSender) GetSlowStartThreshold() int64 {
// Implementation here
return 0
}
@@ -299,8 +297,10 @@ func (b *BBRSender) NumStartupRTTs() int64 {
}
func (b *BBRSender) GetMinRTT() time.Duration {
// Implementation here
return 0
if b.minRTT != 0 {
return b.minRTT
}
return b.rttStats.SmoothedRTT()
}
func (b *BBRSender) IsAtFullBandwidth() bool {

View File

@@ -69,7 +69,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
}
if groupOption.IncludeAllProviders {
groupOption.Use = append(groupOption.Use, AllProviders...)
groupOption.Use = AllProviders
}
if groupOption.IncludeAllProxies {
if groupOption.Filter != "" {

View File

@@ -740,8 +740,7 @@ return view.extend({
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/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
'Can be overrides by <code>rules.[].client_subnet</code>. Will overrides <code>dns.client_subnet</code>.'));
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
/* DNS servers end */
@@ -949,8 +948,7 @@ return view.extend({
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/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
'Will overrides <code>dns.client_subnet</code> and <code>servers.[].client_subnet</code>.'));
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
/* DNS rules end */
/* Custom routing settings end */

View File

@@ -479,8 +479,7 @@ return view.extend({
o = s.option(form.Value, 'tls_sni', _('TLS SNI'),
_('Used to verify the hostname on the returned certificates unless insecure is given.'));
o.depends({'tls': '1', 'tls_reality': '0'});
o.depends({'tls': '1', 'tls_reality': null});
o.depends('tls', '1');
o.modalonly = true;
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

View File

@@ -40,6 +40,7 @@ chain input {
iifname {{ tun_name }} counter accept comment "!{{ cfgname }}: accept tun input"
{% endif %}
{%
if (auto_firewall === '1')
uci.foreach(cfgname, 'server', (s) => {
if (s.enabled !== '1')
return;

View File

@@ -740,8 +740,7 @@ return view.extend({
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/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
'Can be overrides by <code>rules.[].client_subnet</code>. Will overrides <code>dns.client_subnet</code>.'));
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
/* DNS servers end */
@@ -949,8 +948,7 @@ return view.extend({
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/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.<br/>' +
'Will overrides <code>dns.client_subnet</code> and <code>servers.[].client_subnet</code>.'));
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
/* DNS rules end */
/* Custom routing settings end */

View File

@@ -479,8 +479,7 @@ return view.extend({
o = s.option(form.Value, 'tls_sni', _('TLS SNI'),
_('Used to verify the hostname on the returned certificates unless insecure is given.'));
o.depends({'tls': '1', 'tls_reality': '0'});
o.depends({'tls': '1', 'tls_reality': null});
o.depends('tls', '1');
o.modalonly = true;
o = s.option(form.DynamicList, 'tls_alpn', _('TLS ALPN'),

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@ chain input {
iifname {{ tun_name }} counter accept comment "!{{ cfgname }}: accept tun input"
{% endif %}
{%
if (auto_firewall === '1')
uci.foreach(cfgname, 'server', (s) => {
if (s.enabled !== '1')
return;

View File

@@ -916,7 +916,8 @@ add_firewall_rule() {
WAN_IP=$(get_wan_ip)
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
unset WAN_IP

View File

@@ -308,9 +308,9 @@ dependencies = [
[[package]]
name = "blake3"
version = "1.5.2"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92"
checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210"
dependencies = [
"arrayref",
"arrayvec",

View File

@@ -30,13 +30,13 @@ define Download/geosite
HASH:=dbaba085b1de1b8b875f3db78fb367aef080f24993af01abe21f4d4ba99048be
endef
GEOSITE_IRAN_VER:=202407080029
GEOSITE_IRAN_VER:=202407150030
GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER)
define Download/geosite-ir
URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/
URL_FILE:=iran.dat
FILE:=$(GEOSITE_IRAN_FILE)
HASH:=d3c6bd7daab2c720c4c9796c3b31ee7328273cc52b9ff6621e63c5e0513f9a49
HASH:=73f55b3bc7ae33c63a9eb5ae11be288d9500b89ffa824584a57eb89cbc84a8d6
endef
define Package/v2ray-geodata/template

View File

@@ -78,6 +78,9 @@ jobs:
# Include amd64 on all platforms.
goos: [windows, freebsd, openbsd, linux, darwin]
goarch: [amd64, 386]
gotoolchain: [""]
patch-assetname: [""]
exclude:
# Exclude i386 on darwin
- goarch: 386
@@ -152,6 +155,16 @@ jobs:
goarch: arm
goarm: 7
# 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
runs-on: ubuntu-latest
@@ -166,14 +179,15 @@ jobs:
- name: Show workflow information
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 "ASSET_NAME=$_NAME" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
go-version: ${{ matrix.gotoolchain || '1.22' }}
check-latest: true
- name: Get project dependencies

View File

@@ -32,7 +32,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
go-version: '1.22'
check-latest: true
- name: Restore Cache
uses: actions/cache/restore@v4

View File

@@ -27,8 +27,7 @@
- [ghcr.io/xtls/xray-core](https://ghcr.io/xtls/xray-core) (**Official**)
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
- 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)
- [Xray-UI](https://github.com/qist/xray-ui), [X-UI](https://github.com/sing-web/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)
- [Hiddify](https://github.com/hiddify/hiddify-config)
- [Marzban](https://github.com/Gozargah/Marzban)
- [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))
- Windows
- [v2rayN](https://github.com/2dust/v2rayN)
- [NekoRay](https://github.com/Matsuridayo/nekoray)
- [Furious](https://github.com/LorenEteval/Furious)
- [HiddifyN](https://github.com/hiddify/HiddifyN)
- [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient)
- Android
- [v2rayNG](https://github.com/2dust/v2rayNG)
- [HiddifyNG](https://github.com/hiddify/HiddifyNG)
- [X-flutter](https://github.com/XTLS/X-flutter)
- iOS & macOS arm64
- [FoXray](https://apps.apple.com/app/foxray/id6448898396)
@@ -85,7 +81,6 @@
- [FoXray](https://apps.apple.com/app/foxray/id6448898396)
- Linux
- [v2rayA](https://github.com/v2rayA/v2rayA)
- [NekoRay](https://github.com/Matsuridayo/nekoray)
- [Furious](https://github.com/LorenEteval/Furious)
## Others that support VLESS, XTLS, REALITY, XUDP, PLUX...
@@ -98,21 +93,15 @@
- [XTLS/libXray](https://github.com/XTLS/libXray)
- [xtlsapi](https://github.com/hiddify/xtlsapi)
- [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite)
- [XrayKit](https://github.com/arror/XrayKit)
- [Xray-core-python](https://github.com/LorenEteval/Xray-core-python)
- [xray-api](https://github.com/XVGuardian/xray-api)
- [XrayR](https://github.com/XrayR-project/XrayR)
- [XrayR-release](https://github.com/XrayR-project/XrayR-release)
- [XrayR-V2Board](https://github.com/missuo/XrayR-V2Board)
- [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
- [Clash Verge](https://github.com/zzzgydi/clash-verge)
- [clashN](https://github.com/2dust/clashN)
- [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)
- [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

View File

@@ -151,7 +151,7 @@ func LogInfo(ctx context.Context, 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{}) {
@@ -159,7 +159,7 @@ func LogWarning(ctx context.Context, 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{}) {
@@ -167,7 +167,7 @@ func LogError(ctx context.Context, 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{}) {

View File

@@ -21,7 +21,7 @@ import (
var (
Version_x byte = 1
Version_y byte = 8
Version_z byte = 17
Version_z byte = 18
)
var (

View File

@@ -1,6 +1,6 @@
module github.com/xtls/xray-core
go 1.22
go 1.21.4
require (
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0

View File

@@ -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)
- 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)
- 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)
[![aur yass-proxy-gtk3](https://img.shields.io/aur/version/yass-proxy-gtk3)](https://aur.archlinux.org/packages/yass-proxy-gtk3)
[![aur yass-proxy-qt5](https://img.shields.io/aur/version/yass-proxy-qt5)](https://aur.archlinux.org/packages/yass-proxy-qt5)

View File

@@ -1859,6 +1859,9 @@ The following extractors use this feature:
#### bilibili
* `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
<!-- MANPAGE: MOVE "INSTALLATION" SECTION HERE -->

View File

@@ -929,6 +929,11 @@ class TestUtil(unittest.TestCase):
'acodec': 'none',
'dynamic_range': 'DV',
})
self.assertEqual(parse_codecs('fLaC'), {
'vcodec': 'none',
'acodec': 'flac',
'dynamic_range': None,
})
self.assertEqual(parse_codecs('theora, vorbis'), {
'vcodec': 'theora',
'acodec': 'vorbis',

View File

@@ -1,6 +1,8 @@
from .common import InfoExtractor
from ..networking.exceptions import HTTPError
from ..utils import (
ExtractorError,
parse_codecs,
try_get,
url_or_none,
urlencode_postdata,
@@ -12,6 +14,7 @@ class DigitalConcertHallIE(InfoExtractor):
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]+)?'
_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
_NETRC_MACHINE = 'digitalconcerthall'
_TESTS = [{
@@ -68,33 +71,42 @@ class DigitalConcertHallIE(InfoExtractor):
}]
def _perform_login(self, username, password):
token_response = self._download_json(
login_token = self._download_json(
self._OAUTH_URL,
None, 'Obtaining token', errnote='Unable to obtain token', data=urlencode_postdata({
'affiliate': 'none',
'grant_type': 'device',
'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_version': '1.0.0',
'app_distributor': 'berlinphil',
'app_version': '1.84.0',
'client_secret': '2ySLN+2Fwb',
}), headers={
'Content-Type': 'application/x-www-form-urlencoded',
})
self._ACCESS_TOKEN = token_response['access_token']
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'User-Agent': self._USER_AGENT,
})['access_token']
try:
self._download_json(
login_response = self._download_json(
self._OAUTH_URL,
None, note='Logging in', errnote='Unable to login', data=urlencode_postdata({
'grant_type': 'password',
'username': username,
'password': password,
}), 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',
'Authorization': f'Bearer {self._ACCESS_TOKEN}',
'Authorization': f'Bearer {login_token}',
'User-Agent': self._USER_AGENT,
})
except ExtractorError:
self.raise_login_required(msg='Login info incorrect')
except ExtractorError as error:
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):
if not self._ACCESS_TOKEN:
@@ -108,11 +120,15 @@ class DigitalConcertHallIE(InfoExtractor):
'Accept': 'application/json',
'Authorization': f'Bearer {self._ACCESS_TOKEN}',
'Accept-Language': language,
'User-Agent': self._USER_AGENT,
})
formats = []
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 {
'id': video_id,
@@ -140,13 +156,15 @@ class DigitalConcertHallIE(InfoExtractor):
f'https://api.digitalconcerthall.com/v2/{api_type}/{video_id}', video_id, headers={
'Accept': 'application/json',
'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', ..., ...))
if type_ == 'work':
videos = [videos[int(part) - 1]]
album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name', {str}))
thumbnail = traverse_obj(vid_info, (
'image', ..., {self._proto_relative_url}, {url_or_none},
{lambda x: x.format(width=0, height=0)}, any)) # NB: 0x0 is the original size

View File

@@ -43,6 +43,7 @@ from ..utils import (
xpath_text,
xpath_with_ns,
)
from ..utils._utils import _UnsafeExtensionError
class GenericIE(InfoExtractor):
@@ -2446,9 +2447,13 @@ class GenericIE(InfoExtractor):
if not is_html(first_bytes):
self.report_warning(
'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({
'direct': True,
'url': url,
'ext': ext,
})
return info_dict

View File

@@ -871,7 +871,7 @@ class SoundcloudUserPermalinkIE(SoundcloudPagedPlaylistBaseIE):
'id': '30909869',
'title': 'neilcic',
},
'playlist_mincount': 23,
'playlist_mincount': 22,
}]
def _real_extract(self, url):
@@ -880,7 +880,7 @@ class SoundcloudUserPermalinkIE(SoundcloudPagedPlaylistBaseIE):
self._resolv_url(url), user_id, 'Downloading user info', headers=self._HEADERS)
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):

View File

@@ -270,7 +270,7 @@ def build_innertube_clients():
THIRD_PARTY = {
'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])
for client, ytcfg in tuple(INNERTUBE_CLIENTS.items()):
@@ -3702,15 +3702,15 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
return pr_id
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 'web' in clients:
experiments = traverse_obj(master_ytcfg, (
'WEB_PLAYER_CONTEXT_CONFIGS', ..., 'serializedExperimentIds', {str}, {lambda x: x.split(',')}, ..., {str}))
'WEB_PLAYER_CONTEXT_CONFIGS', ..., 'serializedExperimentIds', {lambda x: x.split(',')}, ...))
if all(x in experiments for x in self._POTOKEN_EXPERIMENTS):
self.report_warning(
'Webpage contains broken formats (poToken experiment detected). Ignoring initial player response')
master_ytcfg = self._get_default_ytcfg()
else:
ignore_initial_response = True
initial_pr = self._search_json(
self._YT_INITIAL_PLAYER_RESPONSE_RE, webpage, 'initial player response', video_id, fatal=False)
@@ -3740,8 +3740,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
skipped_clients = {}
while clients:
client, base_client, variant = _split_innertube_client(clients.pop())
player_ytcfg = master_ytcfg if client == 'web' else {}
if 'configs' not in self._configuration_arg('player_skip') and client != 'web':
player_ytcfg = {}
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_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)
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):
try:
pr = pr or self._extract_player_response(
@@ -3765,7 +3767,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
break
experiments = traverse_obj(pr, (
'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):
pr = None
retry.error = ExtractorError('API returned broken formats (poToken experiment detected)', expected=True)

View File

@@ -2984,6 +2984,7 @@ def parse_codecs(codecs_str):
str.strip, codecs_str.strip().strip(',').split(','))))
vcodec, acodec, scodec, hdr = None, None, None, None
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('.')
if parts[0] in ('avc1', 'avc2', 'avc3', 'avc4', 'vp9', 'vp8', 'hev1', 'hev2',
'h263', 'h264', 'mp4v', 'hvc1', 'av1', 'theora', 'dvh1', 'dvhe'):