From f5e06f0ae999db318a893154cf42095790ad0d0d Mon Sep 17 00:00:00 2001 From: woniuzfb <47843848+woniuzfb@users.noreply.github.com> Date: Fri, 4 Jun 2021 00:05:33 +0800 Subject: [PATCH] feat: alternative editor,command; fix: arch, mmproxy, ulimit --- README.md | 2 + docs/iptv.sh | 799 +++++++++++++++++++++++----------- i18n/iptv.sh.pot | 624 +++++++++++++------------- i18n/make-pot.sh | 13 +- i18n/po/iptv.sh-en.mo | Bin 23238 -> 24664 bytes iptv.sh | 799 +++++++++++++++++++++++----------- scripts/fengshows_proxy.js | 1 + scripts/stream_proxy.js | 1 + scripts/xtream_codes_proxy.js | 1 + 9 files changed, 1416 insertions(+), 824 deletions(-) diff --git a/README.md b/README.md index fccf799..3335c74 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ tv c # change/update language ## 目录 +- [目录](#目录) - [一键管理 nginx 脚本](#一键管理-nginx-脚本) - [一键管理 openresty 脚本](#一键管理-openresty-脚本) - [一键管理 xray 脚本](#一键管理-xray-脚本) @@ -35,6 +36,7 @@ nx # 打开 Nginx 管理面板 - 使用官方 crossplane 解析配置 - 支持修改最多五级指令 +- SNI/SSL/APLN 分流 --- diff --git a/docs/iptv.sh b/docs/iptv.sh index ca3f5b9..9ef1017 100755 --- a/docs/iptv.sh +++ b/docs/iptv.sh @@ -1,17 +1,17 @@ #!/bin/bash -# FFmpeg / nginx / openresty / xray / v2ray / cloudflare partner,workers / ibm cf / armbian / proxmox Wrapper Script By MTimer +# FFmpeg / nginx / openresty / xray / v2ray / cloudflare partner,workers / ibm cf / armbian / proxmox ve Wrapper Script By MTimer # Copyright (C) 2019-2021 # Released under GPL Version 3 License set -euo pipefail -sh_ver="1.80.8" +sh_ver="1.80.9" sh_debug=0 export LANGUAGE= export LC_ALL= export LANG=en_US.UTF-8 SH_LINK="https://woniuzfb.github.io/iptv/iptv.sh" -SH_LINK_BACKUP="http://tv.epub.fun/iptv.sh" +SH_LINK_FALLBACK="http://tv.epub.fun/iptv.sh" SH_FILE="/usr/local/bin/tv" i18n_FILE="/usr/local/bin/tv-i18n" OR_FILE="/usr/local/bin/or" @@ -36,7 +36,7 @@ FFMPEG_LOG_ROOT="$IPTV_ROOT/ffmpeg" FFMPEG_MIRROR_LINK="http://pngquant.com/ffmpeg" V2_FILE="/usr/local/bin/v2" V2_LINK="https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh" -V2_LINK_BACKUP="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh" +V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh" V2CTL_FILE="/usr/local/bin/v2ctl" V2_CONFIG="/usr/local/etc/v2ray/config.json" X_FILE="/usr/local/bin/x" @@ -51,18 +51,18 @@ VIP_USERS_ROOT="$VIP_ROOT/users" C_ROOT="$IPTV_ROOT/c" MD5SUM_FILE="$C_ROOT/md5sum" MD5SUM_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/md5sum.c" -MD5SUM_LINK_BACKUP="$FFMPEG_MIRROR_LINK/md5sum.c" +MD5SUM_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/md5sum.c" CREATOR_FILE="$IPTV_ROOT/HLS-Stream-Creator.sh" CF_FILE="/usr/local/bin/cf" CF_CONFIG="$HOME/cloudflare.json" CF_WORKERS_ROOT="$HOME/workers" CF_WORKERS_FILE="$CF_WORKERS_ROOT/cloudflare_workers.py" CF_WORKERS_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/cloudflare_workers.py" -CF_WORKERS_LINK_BACKUP="$FFMPEG_MIRROR_LINK/cloudflare_workers.py" +CF_WORKERS_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/cloudflare_workers.py" STREAM_PROXY_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/stream_proxy.js" -STREAM_PROXY_LINK_BACKUP="$FFMPEG_MIRROR_LINK/stream_proxy.js" +STREAM_PROXY_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/stream_proxy.js" XTREAM_CODES_PROXY_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/xtream_codes_proxy.js" -XTREAM_CODES_PROXY_LINK_BACKUP="$FFMPEG_MIRROR_LINK/xtream_codes_proxy.js" +XTREAM_CODES_PROXY_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xtream_codes_proxy.js" IBM_FILE="/usr/local/bin/ibm" IBM_APPS_ROOT="$HOME/ibm_apps" IBM_CONFIG="$HOME/ibm.json" @@ -102,11 +102,11 @@ ReleaseCheck() then release="rpm" break - elif grep -Eqi "Ubuntu" < "$release_file" + elif grep -qi "Ubuntu" < "$release_file" then release="ubu" break - elif grep -Eqi "Debian" < "$release_file" + elif grep -qi "Debian" < "$release_file" then release="deb" break @@ -120,6 +120,36 @@ ReleaseCheck() fi } +ArchCheck() +{ + [ -n "${arch:-}" ] && return 0 + + arch=$(uname -m) + + if grep -Eqi "x86_64|amd64" <<< "$arch" + then + arch="x86_64" + elif grep -Eqi "i386|i686" <<< "$arch" + then + arch="i386" + elif grep -Eqi "aarch64|armv8" <<< "$arch" + then + arch="arm64" + elif grep -qi "armv7" <<< "$arch" + then + arch="armhf" + elif grep -qi "armv6" <<< "$arch" + then + arch="armv6l" + elif grep -qi "arm" <<< "$arch" + then + arch="armel" + elif grep -qi "s390" <<< "$arch" + then + arch="s390x" + fi +} + DebFixSources() { if [ "${deb_fix:-1}" -eq 1 ] @@ -1390,7 +1420,7 @@ ShFileCheck() Println "`eval_gettext \"\\\$info 脚本下载完成\"`" else Println "`eval_gettext \"\\\$error 无法连接到 Github ! 尝试备用链接...\"`" - if curl -s -Lm 30 "$SH_LINK_BACKUP" -o "${SH_FILE}_tmp" + if curl -s -Lm 30 "$SH_LINK_FALLBACK" -o "${SH_FILE}_tmp" then mv "${SH_FILE}_tmp" "$SH_FILE" chmod +x "$SH_FILE" @@ -1433,7 +1463,7 @@ ShFileUpdate() fi else Println "`eval_gettext \"\\\$error 无法连接到 Github ! 尝试备用链接...\"`" - if curl -s -Lm 30 "$SH_LINK_BACKUP" -o "${SH_FILE}_tmp" + if curl -s -Lm 30 "$SH_LINK_FALLBACK" -o "${SH_FILE}_tmp" then mv "${SH_FILE}_tmp" "$SH_FILE" chmod +x "$SH_FILE" @@ -1544,6 +1574,64 @@ CrossplaneInstall() pip3 install crossplane } +GoInstall() +{ + if [[ -x $(command -v go) ]] + then + go_version_list=($(go version)) + if [[ "${go_version_list[2]}" =~ ^go([0-9]+)\.([0-9]+)\. ]] && [ "${BASH_REMATCH[1]}" -ge 1 ] && [ "${BASH_REMATCH[2]}" -ge 11 ] + then + return 0 + fi + fi + + ArchCheck + + DepInstall curl + + go_version="" + + while IFS= read -r line + do + if [[ $line == *"goVersion = "* ]] + then + go_version=${line#*\"} + go_version=${go_version%\"*} + break + fi + done < <(curl -s -Lm 20 -H "User-Agent: $USER_AGENT_BROWSER" "https://golang.org/doc/install" 2> /dev/null) + + go_version=${go_version:-1.16.5} + + if [ "$arch" == "i386" ] + then + go_package="$go_version.linux-386.tar.gz" + elif [ "$arch" == "x86_64" ] + then + go_package="$go_version.linux-amd64.tar.gz" + elif [ "$arch" == "arm64" ] || [ "$arch" == "armv6l" ] + then + go_package="$go_version.linux-$arch.tar.gz" + else + DepInstall golang + return 0 + fi + + if ! curl -L https://golang.org/dl/$go_package -o ~/$go_package && ! curl -L https://gomirrors.org/dl/$go_package -o ~/$go_package + then + Println "$error 下载 golang 失败, 请稍后再试\n" + exit 1 + fi + + rm -rf /usr/local/go && tar -C /usr/local -xzf ~/$go_package + + if [[ ! -x $(command -v go) ]] + then + export PATH=$PATH:/usr/local/go/bin + echo "export PATH=\$PATH:/usr/local/go/bin" >> /etc/profile + fi +} + FFmpegInstall() { FFMPEG_ROOT=$(dirname "$IPTV_ROOT"/ffmpeg-git-*/ffmpeg) @@ -1551,19 +1639,29 @@ FFmpegInstall() if [ ! -e "$FFMPEG" ] then Println "`eval_gettext \"\\\$info 开始下载/安装 FFmpeg...\"`" - [ -z "${arch:-}" ] && arch=$(uname -m) - if [ "$arch" == "aarch64" ] - then - ffmpeg_package="ffmpeg-git-arm64-static.tar.xz" - elif grep -q 64 <<< "$arch" + ArchCheck + if [ "$arch" == "x86_64" ] then ffmpeg_package="ffmpeg-git-amd64-static.tar.xz" - else + elif [ "$arch" == "i386" ] + then + ffmpeg_package="ffmpeg-git-i686-static.tar.xz" + elif [ "$arch" == "armv6l" ] + then + ffmpeg_package="ffmpeg-git-armel-static.tar.xz" + elif grep -q "arm" <<< "$arch" + then ffmpeg_package="ffmpeg-git-$arch-static.tar.xz" + else + Println "$error FFmpeg 不支持当前系统\n" + exit 1 fi FFMPEG_PACKAGE_FILE="$IPTV_ROOT/$ffmpeg_package" - curl -L "$FFMPEG_MIRROR_LINK/builds/$ffmpeg_package" -o "$FFMPEG_PACKAGE_FILE" - [ ! -e "$FFMPEG_PACKAGE_FILE" ] && Println "`eval_gettext \"\\\$error FFmpeg 下载失败 !\"`" && exit 1 + if ! curl -L "$FFMPEG_MIRROR_LINK/builds/$ffmpeg_package" -o "$FFMPEG_PACKAGE_FILE" + then + Println "`eval_gettext \"\\\$error FFmpeg 下载失败 !\"`" + exit 1 + fi tar xJf "$FFMPEG_PACKAGE_FILE" -C "$IPTV_ROOT" && rm -f "${FFMPEG_PACKAGE_FILE:-notfound}" FFMPEG=$(dirname "$IPTV_ROOT"/ffmpeg-git-*/ffmpeg) [ ! -e "$FFMPEG" ] && Println "`eval_gettext \"\\\$error FFmpeg 解压失败 !\"`" && exit 1 @@ -2389,7 +2487,8 @@ Cflags: -I\${includedir} JQInstall() { - if [[ -x $(command -v armbian-config) ]] + ArchCheck + if grep -q "arm" <<< "$arch" then if ! /usr/local/bin/jq -V > /dev/null 2>&1 then @@ -2417,7 +2516,6 @@ JQInstall() #experimental# grep -Po '"tag_name": "jq-\K.*?(?=")' if jq_ver=$(curl -s -m 10 "$FFMPEG_MIRROR_LINK/jq.json" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') then - [ -z "${arch:-}" ] && arch=$(uname -m) if grep -q 64 <<< "$arch" then jq_package="jq-linux64" @@ -2547,6 +2645,7 @@ Install() }' > "$CHANNELS_FILE" ln -sf "$IPTV_ROOT"/ffmpeg-git-*/ff* /usr/local/bin/ + Println "`eval_gettext \"\\\$info 安装完成\"`\n" fi } @@ -9983,7 +10082,7 @@ EditChannelMenu() EditForSecurity ;; *) - echo "$i18n_input_correct_no...\n" && exit 1 + Println "$i18n_input_correct_no...\n" && exit 1 ;; esac @@ -10411,7 +10510,6 @@ StartChannel() chnl_cookies="" if [[ $chnl_stream_link =~ inews ]] then - chnl_audio_codec="aac" if [ "$chnl_video_codec" == "copy" ] && [[ ! $chnl_output_flags =~ -map ]] then chnl_output_flags="$chnl_output_flags -map 0:p:0" @@ -10427,7 +10525,7 @@ StartChannel() chnl_output_flags="$chnl_output_flags -vsync 0" fi fi - if [[ ! $chnl_output_flags =~ -ar ]] + if [ "$chnl_audio_codec" != "copy" ] && [[ ! $chnl_output_flags =~ -ar ]] then chnl_output_flags="$chnl_output_flags -ar 32000" fi @@ -11532,7 +11630,7 @@ StopChannel() rm -rf "$chnl_output_dir_root" rm -rf "$FFMPEG_LOG_ROOT/$chnl_pid.pid" else - kill "$chnl_pid" 2> /dev/null + kill "$chnl_pid" 2> /dev/null || true if ! flock -E 1 -w 30 -x "$FFMPEG_LOG_ROOT/$chnl_pid.pid" rm -rf "$FFMPEG_LOG_ROOT/$chnl_pid.pid" then MonitorError "频道[ $chnl_channel_name ] 进程 $chnl_pid 不存在" @@ -14208,7 +14306,7 @@ ScheduleSingteltv() program_sys_time=$(date -d "${program_times[program_i]}" +%s) [ -n "$schedule" ] && schedule="$schedule," schedule=$schedule'{ - "title":"'"${program_titles[program_i]}"'", + "title":"'"${program_titles[program_i]//\"/}"'", "time":"'"$program_time"'", "sys_time":"'"$program_sys_time"'" }' @@ -21241,7 +21339,7 @@ NginxInstall() nginx_package_name=${nginx_package_name%%.tar.gz*} break fi - done < <(curl -s -Lm 10 -H "User-Agent: $USER_AGENT_BROWSER" "https://nginx.org/en/download.html" 2> /dev/null) + done < <(curl -s -Lm 20 -H "User-Agent: $USER_AGENT_BROWSER" "https://nginx.org/en/download.html" 2> /dev/null) if [ ! -d "./$nginx_package_name" ] then @@ -21340,7 +21438,7 @@ NginxViewStatus() then Println "$error $nginx_name 未安装 !\n" else - systemctl status $nginx_name.service --no-pager + systemctl --no-pager status $nginx_name fi } @@ -21363,6 +21461,11 @@ NginxToggle() NginxRestart() { + if ! $NGINX_FILE -t + then + Println "$error 请检查配置错误\n" + exit 1 + fi if systemctl restart $nginx_name then Println "$info $nginx_name 重启成功\n" @@ -21779,6 +21882,15 @@ NginxConfigDomain() fi Println "$info flv 配置添加成功\n" else + server_name=${nginx_domain_servers_name[nginx_domain_servers_index]} + + if [[ $server_name =~ , ]] + then + IFS="," read -r -a domains <<< "$server_name" + + echo + inquirer list_input "选择域名: " domains server_name + fi updated=0 NginxAddNodejs if [ "$updated" -eq 1 ] @@ -22649,7 +22761,7 @@ NginxAddLocalhost() NginxAddNodejs() { - server_ip=${server_ip:-$(GetServerIp)} + proxy_cookie_domain=${server_name:-$(GetServerIp)} directive_location_1=' {"directive":"location","args":["=","/"],"block":[ @@ -22658,7 +22770,7 @@ NginxAddNodejs() {"directive":"proxy_cache_bypass","args":["1"]}, {"directive":"proxy_no_cache","args":["1"]}, {"directive":"proxy_cookie_path","args":["/","/$samesite_none"]}, - {"directive":"proxy_cookie_domain","args":["localhost","'"$server_ip"'"]} + {"directive":"proxy_cookie_domain","args":["localhost","'"$proxy_cookie_domain"'"]} ]}' directive_location_2=' @@ -22681,7 +22793,7 @@ NginxAddNodejs() {"directive":"proxy_cache_bypass","args":["1"]}, {"directive":"proxy_no_cache","args":["1"]}, {"directive":"proxy_cookie_path","args":["/","/$samesite_none"]}, - {"directive":"proxy_cookie_domain","args":["localhost","'"$server_ip"'"]} + {"directive":"proxy_cookie_domain","args":["localhost","'"$proxy_cookie_domain"'"]} ]}' directive_location_5=' @@ -22870,9 +22982,9 @@ NginxAddSameSiteNone() NginxAddDirective 2 directive_default='{"directive":"default","args":["; Secure"]}' - directive_chrome='{"directive":"~Chrom[^ \\/]+\\/8[\\d][\\.\\d]*","args":["; Secure; SameSite=None"]}' + directive_chrome='{"directive":"~Chrom[^ \\/]+\\/[89][\\d][\\.\\d]*","args":["; Secure; SameSite=None"]}' - directives=( default '~Chrom[^ \\/]+\\/8[\\d][\\.\\d]*' ) + directives=( default '~Chrom[^ \\/]+\\/[89][\\d][\\.\\d]*' ) directives_val=( default chrome ) check_directives=() check_args=( '["; Secure"]' ) @@ -23632,7 +23744,7 @@ NginxConfigDirective() NginxConfigLocalhost() { echo - config_localhost_options=( '修改指令' '添加 flv 设置' '添加 nodejs 设置' '添加 SNI 域名分流' '添加 SSL 协议分流' '添加 ALPN 协议分流' '添加 分流后端' '删除 SNI 域名分流' '删除 SSL 协议分流' '删除 ALPN 协议分流' '删除 分流后端' ) + config_localhost_options=( '修改指令' '添加 flv 设置' '添加 nodejs 设置' '添加 SNI 域名分流' '添加 SSL 协议分流' '添加 ALPN 协议分流' '添加 分流后端' '删除 SNI 域名分流' '删除 SSL 协议分流' '删除 ALPN 协议分流' '删除 分流后端' '取消' ) inquirer list_input_index "选择操作" config_localhost_options config_localhost_options_index if [ "$config_localhost_options_index" -eq 0 ] @@ -23666,6 +23778,9 @@ NginxConfigLocalhost() NginxBuildConf parse_out fi Println "$info nodejs 配置添加成功\n" + elif [ "$config_localhost_options_index" -eq 11 ] + then + Println "$i18n_canceled...\n" else NginxCheckLocalhost NginxGetStream @@ -23765,6 +23880,7 @@ NginxConfigLocalhost() Println "ALPN 协议分流:\n\n${nginx_stream_alpn_protocols_list:-无}\n\n" inquirer text_input "输入指令(分流 ALPN 协议)" alpn_protocols_directive "$i18n_cancel" ExitOnCancel alpn_protocols_directive + alpn_protocols_directive=${alpn_protocols_directive//\\/\\\\} echo inquirer text_input "输入指令值(分流后端名称)" alpn_protocols_args "$i18n_cancel" ExitOnCancel alpn_protocols_args @@ -24254,7 +24370,7 @@ NginxLogRotate() compress delaycompress notifempty - create 660 nginx root + create 660 '"$nginx_name"' root sharedscripts postrotate [ ! -f '"$nginx_prefix"'/logs/nginx.pid ] || /bin/kill -USR1 `cat '"$nginx_prefix"'/logs/nginx.pid` @@ -24265,7 +24381,7 @@ NginxLogRotate() Println "$error 日志切割定时任务设置成功 !\n" fi else - LOGROTATE_FILE=$(command -v logrotate) + LOGROTATE_FILE=$(command -v logrotate) || LOGROTATE_FILE="" if [ ! -x "$LOGROTATE_FILE" ] then @@ -24284,16 +24400,16 @@ NginxLogRotate() compress delaycompress notifempty - create 660 nginx root + create 660 '"$nginx_name"' root sharedscripts postrotate [ ! -f '"$nginx_prefix"'/logs/nginx.pid ] || /bin/kill -USR1 `cat '"$nginx_prefix"'/logs/nginx.pid` endscript } ' - fi + fi - logrotate="$logrotate + logrotate="$logrotate $IPTV_ROOT/*.log { monthly missingok @@ -24757,26 +24873,40 @@ NodejsInstall() echo -n "...100%" && Println "$info nodejs 安装完成" } -NodejsInstallMongodb() +ResourceLimit() { - Println "$info 安装 mongodb, 请等待(国内可能无法安装)..." + ReleaseCheck + + if [ ! -e /proc/sys/fs/file-max ] + then + echo 65536 > /proc/sys/fs/file-max + echo "fs.file-max=65536" >> /etc/sysctl.conf + fi + + file_max=$(< /proc/sys/fs/file-max) + + if [ "$file_max" -lt 65000 ] + then + file_max=$((file_max*95/100)) + else + file_max=64000 + fi + limits=( - "root soft nofile 65535" - "root hard nofile 65535" - "root soft nproc 65535" - "root hard nproc 65535" - "* soft nofile 64000" - "* hard nofile 64000" - "mongod soft fsize unlimited" - "mongod hard fsize unlimited" - "mongod soft cpu unlimited" - "mongod hard cpu unlimited" - "mongod soft as unlimited" - "mongod hard as unlimited" - "mongod soft memlock unlimited" - "mongod hard memlock unlimited" - "mongod soft nproc 64000" - "mongod hard nproc 64000" + "$USER soft fsize unlimited" + "$USER hard fsize unlimited" + "$USER soft cpu unlimited" + "$USER hard cpu unlimited" + "$USER soft as unlimited" + "$USER hard as unlimited" + "$USER soft memlock unlimited" + "$USER hard memlock unlimited" + "$USER soft nofile $file_max" + "$USER hard nofile $file_max" + "$USER soft nproc 64000" + "$USER hard nproc 64000" + "* soft nofile $file_max" + "* hard nofile $file_max" ) limits_append="" @@ -24790,23 +24920,77 @@ NodejsInstallMongodb() if [ -n "$limits_append" ] then + # systemd ignores limits set in the /etc/security/limits.conf echo -e "$limits_append" >> "/etc/security/limits.conf" fi ulimit -f unlimited ulimit -t unlimited ulimit -v unlimited - ulimit -n 64000 + ulimit -l unlimited + ulimit -n $file_max ulimit -m unlimited - ulimit -u 32000 + ulimit -u 64000 + + if [ "$release" == "rpm" ] + then + if [ ! -e ~/.bash_profile ] || ! grep -q ulimit < ~/.bash_profile + then +cat >> ~/.bash_profile << EOF +ulimit -f unlimited +ulimit -t unlimited +ulimit -v unlimited +ulimit -l unlimited +ulimit -n $file_max +ulimit -m unlimited +ulimit -u 64000 +EOF + fi + else + if [ ! -e ~/.profile ] || ! grep -q ulimit < ~/.profile + then +cat >> ~/.profile << EOF +ulimit -f unlimited +ulimit -t unlimited +ulimit -v unlimited +ulimit -l unlimited +ulimit -n $file_max +ulimit -m unlimited +ulimit -u 64000 +EOF + fi + fi + + # The limits defined in these files are set by PAM when starting a login session, but daemons started by systemd do not use PAM login sessions + #if [ ! -e /etc/security/limits.d/99-mongodb-nproc.conf ] && ls -A /etc/security/limits.d/*-nproc.conf > /dev/null 2>&1 + #then + # echo -e "mongodb soft nproc 64000\nmongodb hard nproc 64000" > /etc/security/limits.d/99-mongodb-nproc.conf + #fi +} + +NodejsInstallMongodb() +{ + Println "$info 安装 mongodb, 请等待(国内可能无法安装)..." + + ResourceLimit - ReleaseCheck if [ "$release" == "rpm" ] then + ArchCheck + if [ "$arch" == "arm64" ] + then + arch_path="aarch64" + elif [ "$arch" == "x86_64" ] || [ "$arch" == "s390x" ] + then + arch_path="$arch" + else + Println "$error 不支持当前系统\n" + exit 1 + fi printf '%s' " [mongodb-org-4.4] name=MongoDB Repository -baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.4/x86_64/ +baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.4/$arch_path/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc @@ -24823,19 +25007,19 @@ gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc then if grep -q "xenial" < "/etc/apt/sources.list" then - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb [ arch=amd64,arm64,s390x ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list elif grep -q "bionic" < "/etc/apt/sources.list" then - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb [ arch=amd64,arm64,s390x ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list else - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb [ arch=amd64,arm64,s390x ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list fi else if grep -q "stretch" < "/etc/apt/sources.list" then - echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list else - echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list fi fi @@ -24845,16 +25029,16 @@ gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc if [[ $(ps --no-headers -o comm 1) == "systemd" ]] then - if ! systemctl start mongod > /dev/null 2>&1 - then - systemctl daemon-reload - systemctl start mongod > /dev/null 2>&1 - fi + sed -i "s/LimitNOFILE=.*/LimitNOFILE=$file_max/" /lib/systemd/system/mongod.service + systemctl daemon-reload + systemctl start mongod systemctl enable mongod else service mongod start fi + sleep 3 + Println "$info mongodb 安装成功" } @@ -24885,6 +25069,16 @@ NodejsConfig() then NginxListDomain NginxSelectDomainServer + + server_name=${nginx_domain_servers_name[nginx_domain_servers_index]} + + if [[ $server_name =~ , ]] + then + IFS="," read -r -a domains <<< "$server_name" + + echo + inquirer list_input "选择域名: " domains server_name + fi else NginxListLocalhost NginxSelectLocalhostServer @@ -25069,7 +25263,7 @@ V2rayInstall() if [ "$v2ray_name" == "v2ray" ] then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25077,7 +25271,7 @@ V2rayInstall() | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25122,7 +25316,7 @@ V2rayUpdate() if [ "$v2ray_name" == "v2ray" ] then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25130,7 +25324,7 @@ V2rayUpdate() | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25263,7 +25457,7 @@ V2rayConfigUpdate() V2rayStatus() { - systemctl status $v2ray_name --no-pager + systemctl --no-pager status $v2ray_name } V2raySetListen() @@ -26477,7 +26671,7 @@ V2rayAddInbound() V2raySetSniffingDomainsExcluded fi - if [ "$self" == "ibm" ] || [ "$self" == "ibm.sh" ] + if [ "$self" == "ibm" ] then V2raySetSecurity V2raySetTag @@ -27808,10 +28002,7 @@ V2rayListInboundAccountLink() Println "$info 安装 ImageMagick" ImageMagickInstall fi - if [[ ! -x $(command -v qrencode) ]] - then - DepInstall qrencode - fi + DepInstall qrencode qrencode -s 1 -o "$HOME/vmess_link.png" "vmess://$vmess_link" /usr/local/bin/imgcat --half-height "$HOME/vmess_link.png" fi @@ -30857,7 +31048,7 @@ TrojanInstall() Println "$info 安装 $trojan_name..." - { curl -s -m 10 "$TR_LINK" || curl -s -m 30 "$TR_LINK_BACKUP"; } \ + { curl -s -m 10 "$TR_LINK" || curl -s -m 30 "$TR_LINK_FALLBACK"; } \ | sed "s+nobody+$trojan_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -32993,7 +33184,7 @@ CloudflareSetWorkerUpstream() then Println "$tip 比如: youdomain.com/path" inquirer text_input "输入 worker: $cf_worker_name 源站地址: " cf_worker_upstream "$i18n_cancel" - ExitOnCancel + ExitOnCancel cf_worker_upstream fi } @@ -33021,7 +33212,7 @@ CloudflareAddWorker() then wrangler generate "stream_proxy" wget --timeout=10 --tries=1 --no-check-certificate "$STREAM_PROXY_LINK" -qO "$CF_WORKERS_ROOT/stream_proxy/index.js" \ - || wget --timeout=10 --tries=3 --no-check-certificate "$STREAM_PROXY_LINK_BACKUP" -qO "$CF_WORKERS_ROOT/stream_proxy/index.js" + || wget --timeout=10 --tries=3 --no-check-certificate "$STREAM_PROXY_LINK_FALLBACK" -qO "$CF_WORKERS_ROOT/stream_proxy/index.js" fi CloudflareSetWorkerName @@ -33035,7 +33226,7 @@ CloudflareAddWorker() then wrangler generate "xtream_codes_proxy" wget --timeout=10 --tries=1 --no-check-certificate "$XTREAM_CODES_PROXY_LINK" -qO "$CF_WORKERS_ROOT/xtream_codes_proxy/index.js" \ - || wget --timeout=10 --tries=3 --no-check-certificate "$XTREAM_CODES_PROXY_LINK_BACKUP" -qO "$CF_WORKERS_ROOT/xtream_codes_proxy/index.js" + || wget --timeout=10 --tries=3 --no-check-certificate "$XTREAM_CODES_PROXY_LINK_FALLBACK" -qO "$CF_WORKERS_ROOT/xtream_codes_proxy/index.js" fi CloudflareSetWorkerName @@ -33337,7 +33528,7 @@ CloudflareDeployWorker() do [ -z "$cf_workers_num" ] && Println "$i18n_canceled...\n" && exit 1 - if [[ $cf_workers_num -eq $((cf_workers_count+1)) ]] + if [ "$cf_workers_num" == "$((cf_workers_count+1))" ] then for((i=0;i 切换/更新 语言\"` " exit @@ -39373,9 +39569,16 @@ then UpdateSelf fi -self=${0##*/} +if [[ -x $(command -v readlink) ]] && [ -L "$0" ] && alternative=$(readlink "$0") && [ -L "$alternative" ] +then + self=${alternative##*/} +else + self=${0##*/} +fi -if [ "$self" == "ibm" ] || [ "$self" == "ibm.sh" ] +self=${self%.*} + +if [ "$self" == "ibm" ] then ShFileCheck @@ -39431,7 +39634,7 @@ then IbmCfMenu fi exit 0 -elif [ "$self" == "cf" ] || [ "$self" == "cf.sh" ] +elif [ "$self" == "cf" ] then ShFileCheck @@ -39483,7 +39686,7 @@ then CloudflarePartnerMenu fi exit 0 -elif [ "$self" == "or" ] || [ "$self" == "or.sh" ] +elif [ "$self" == "or" ] then ShFileCheck @@ -39496,6 +39699,7 @@ then if [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then + ResourceLimit echo "[Unit] Description=$nginx_name After=syslog.target network-online.target remote-fs.target nss-lookup.target @@ -39510,10 +39714,21 @@ ExecStartPost=/bin/sleep 0.1 ExecReload=$nginx_prefix/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT \$MAINPID PrivateTmp=true +# file size +LimitFSIZE=infinity +# cpu time +LimitCPU=infinity +# virtual memory size +LimitAS=infinity +# open files +LimitNOFILE=$file_max +# processes/threads +LimitNPROC=64000 +# locked memory +LimitMEMLOCK=infinity [Install] -WantedBy=multi-user.target -" > /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" @@ -39537,11 +39752,10 @@ WantedBy=multi-user.target ${green}11.${normal} 开关 ${green}12.${normal} 重启 ———————————— - ${green}13.${normal} 删除域名 - ${green}14.${normal} 日志切割 -———————————— - ${green}15.${normal} 安装 nodejs - ${green}16.${normal} 识别 cloudflare/ibm ip + ${green}13.${normal} 配置 日志切割 + ${green}14.${normal} 配置 nodejs + ${green}15.${normal} 识别 cloudflare/ibm ip + ${green}16.${normal} 删除域名 $tip 输入: or 打开面板 @@ -39594,12 +39808,9 @@ WantedBy=multi-user.target NginxRestart ;; 13) - NginxDeleteDomain - ;; - 14) NginxLogRotate ;; - 15) + 14) [ ! -d "$IPTV_ROOT" ] && Println "$error 请先输入 tv 安装 !\n" && exit 1 if [[ ! -x $(command -v node) ]] || [[ ! -x $(command -v npm) ]] then @@ -39617,14 +39828,17 @@ WantedBy=multi-user.target Println "$error nodejs 配置已存在\n" && exit 1 fi ;; - 16) + 15) NginxUpdateCFIBMip ;; + 16) + NginxDeleteDomain + ;; *) Println "$error $i18n_input_correct_number [1-16]\n" ;; esac exit 0 -elif [ "$self" == "nx" ] || [ "$self" == "nx.sh" ] +elif [ "$self" == "nx" ] then ShFileCheck @@ -39637,6 +39851,7 @@ then if [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then + ResourceLimit echo "[Unit] Description=$nginx_name After=syslog.target network-online.target remote-fs.target nss-lookup.target @@ -39651,10 +39866,21 @@ ExecStartPost=/bin/sleep 0.1 ExecReload=$nginx_prefix/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT \$MAINPID PrivateTmp=true +# file size +LimitFSIZE=infinity +# cpu time +LimitCPU=infinity +# virtual memory size +LimitAS=infinity +# open files +LimitNOFILE=$file_max +# processes/threads +LimitNPROC=64000 +# locked memory +LimitMEMLOCK=infinity [Install] -WantedBy=multi-user.target -" > /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" @@ -39678,16 +39904,16 @@ WantedBy=multi-user.target ${green}11.${normal} 开关 ${green}12.${normal} 重启 ———————————— - ${green}13.${normal} 删除域名 - ${green}14.${normal} 日志切割 + ${green}13.${normal} 配置 日志切割 + ${green}14.${normal} 配置 nodejs + ${green}15.${normal} 配置 postfix + ${green}16.${normal} 配置 mmproxy + ${green}17.${normal} 配置 dnscrypt proxy + ${green}18.${normal} 识别 cloudflare/ibm ip + ${green}19.${normal} 删除域名 ———————————— - ${green}15.${normal} 安装 nodejs - ${green}16.${normal} 安装 pdf2htmlEX - ${green}17.${normal} 安装 tesseract - ${green}18.${normal} 配置 postfix - ${green}19.${normal} 配置 mmproxy - ${green}20.${normal} 配置 dnscrypt proxy - ${green}21.${normal} 识别 cloudflare/ibm ip + ${green}20.${normal} 安装 pdf2htmlEX + ${green}21.${normal} 安装 tesseract $tip 输入: nx 打开面板 @@ -39740,12 +39966,9 @@ WantedBy=multi-user.target NginxRestart ;; 13) - NginxDeleteDomain - ;; - 14) NginxLogRotate ;; - 15) + 14) [ ! -d "$IPTV_ROOT" ] && Println "$error 请先输入 tv 安装 !\n" && exit 1 if [[ ! -x $(command -v node) ]] || [[ ! -x $(command -v npm) ]] then @@ -39763,38 +39986,7 @@ WantedBy=multi-user.target Println "$error nodejs 配置已存在\n" && exit 1 fi ;; - 16) - if [[ ! -x $(command -v pdf2htmlEX) ]] - then - echo - AskIfContinue n "`gettext \"因为是编译 pdf2htmlEX, 耗时会很长, 是否继续\"`" - Pdf2htmlInstall - Println "$info pdf2htmlEX 安装完成, 输入 source /etc/profile 可立即使用\n" - else - Println "$error pdf2htmlEX 已存在!\n" - fi - ;; - 17) - if [[ ! -x $(command -v tesseract) ]] - then - DepsCheck - echo - if [ "$release" == "ubu" ] - then - add-apt-repository ppa:alex-p/tesseract-ocr -y - AptUpdate - apt-get -y install tesseract - elif [ "$release" == "deb" ] - then - Println "$info 参考 https://notesalexp.org/tesseract-ocr/ ...\n" - else - Println "$info 参考 https://tesseract-ocr.github.io/tessdoc/Home.html ...\n" - fi - else - Println "$error tesseract 已存在!\n" - fi - ;; - 18) + 15) if [[ ! -x $(command -v postfix) ]] then ReleaseCheck @@ -39856,25 +40048,30 @@ WantedBy=multi-user.target fi Println "$info smtp 设置成功\n" ;; - 19) - if [ ! -d ~/mmproxy ] + 16) + if [ ! -e ~/allowed-subnets.txt ] then - if [[ ! -x $(command -v git) ]] + echo -en "0.0.0.0/0\n::/0\n" > ~/allowed-subnets.txt + fi + + if [[ ! -x "$HOME/go/bin/go-mmproxy" ]] + then + Println "$info 安装 go-mmproxy" + + GoInstall + go get github.com/path-network/go-mmproxy + + if [[ ! -x $(command -v go-mmproxy) ]] then - Spinner "安装 git" GitInstall + export PATH="$PATH:$HOME/go/bin" + ReleaseCheck + if [ "$release" == "rpm" ] + then + echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.bash_profile + else + echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.profile + fi fi - trap ' - rm -rf ~/mmproxy - ' EXIT - cd ~ - git clone https://github.com/cloudflare/mmproxy - cd mmproxy - git clone https://github.com/sustrik/libmill.git - git clone https://github.com/seccomp/libseccomp.git - - make CC=clang - echo -en "0.0.0.0/0\n::/0\n" > allowed-networks.txt - trap - EXIT fi echo @@ -39884,9 +40081,11 @@ WantedBy=multi-user.target if [ "$mmproxy_opotions_index" -eq 0 ] then mmproxy_name="acme" - elif [ "$mmproxy_opotions_index" -eq 0 ] + acme_tip="(acme 监听端口)" + elif [ "$mmproxy_opotions_index" -eq 1 ] then mmproxy_name="ssh" + ssh_tip="(ssh 监听端口)" else echo inquirer text_input "输入 mmproxy 配置名称(英文)" mmproxy_name "$i18n_cancel" @@ -39903,21 +40102,29 @@ WantedBy=multi-user.target fi fi - echo - inquirer text_input "输入 mmproxy 监听端口: " mmproxy_listen_port "随机" + Println "$tip 比如 nginx 分流后端: 127.0.0.1:1234" + inquirer text_input "输入 mmproxy 监听 地址+端口: " mmproxy_listen "随机" - if [ "$mmproxy_listen_port" == "随机" ] + if [ "$mmproxy_listen" == "随机" ] then - mmproxy_listen_port=$(GetFreePort) + mmproxy_listen="127.0.0.1:$(GetFreePort)" fi - echo - inquirer text_input "输入前端(比如 nginx) 分流 ipv4 端口: " mmproxy_target_v4_port "$i18n_cancel" - ExitOnCancel mmproxy_target_v4_port + if [ "$mmproxy_name" == "ssh" ] + then + Println "$tip 请确保已经设置 ssh 监听地址和端口" + fi - echo - inquirer text_input "输入前端(比如 nginx) 分流 ipv6 端口: " mmproxy_target_v6_port "$i18n_cancel" - ExitOnCancel mmproxy_target_v6_port + Println "$tip 比如: 127.0.0.1:2222" + inquirer text_input "输入 ipv4 分流目标 地址+端口${acme_tip:-}${ssh_tip:-}: " mmproxy_target_v4 "$i18n_cancel" + ExitOnCancel mmproxy_target_v4 + + inquirer text_input "输入 ipv6 分流目标 地址+端口${acme_tip:-}${ssh_tip:-}: " mmproxy_target_v6 "[::1]:${mmproxy_target_v4#*:}" + + if [ -e "/etc/systemd/system/mmproxy-$mmproxy_name.service" ] + then + reload=1 + fi echo "[Unit] Description=mmproxy-$mmproxy_name @@ -39925,30 +40132,28 @@ After=syslog.target network-online.target nss-lookup.target Wants=network-online.target [Service] -ExecStart=$HOME/mmproxy/mmproxy --allowed-networks $HOME/mmproxy/allowed-networks.txt -l 127.0.0.1:$mmproxy_listen_port -4 127.0.0.1:$mmproxy_target_v4_port -6 [::1]:$mmproxy_target_v6_port +ExecStart=$HOME/go/bin/go-mmproxy --allowed-subnets $HOME/allowed-subnets.txt -l $mmproxy_listen -4 $mmproxy_target_v4 -6 $mmproxy_target_v6 Restart=on-failure [Install] WantedBy=multi-user.target" > "/etc/systemd/system/mmproxy-$mmproxy_name.service" - if ! grep -q 'iif lo lookup 100' < <(ip rule list) + if [ "${reload:-0}" -eq 1 ] then - ip -4 rule add from 127.0.0.1/8 iif lo table 100 - ip -6 rule add from ::1/128 iif lo table 100 - - ip route add local 0.0.0.0/0 dev lo table 100 - ip -6 route add local ::/0 dev lo table 100 + systemctl daemon-reload + systemctl enable "mmproxy-$mmproxy_name" + systemctl restart "mmproxy-$mmproxy_name" + else + systemctl enable "mmproxy-$mmproxy_name" + systemctl start "mmproxy-$mmproxy_name" fi - systemctl enable "mmproxy-$mmproxy_name" - systemctl start "mmproxy-$mmproxy_name" - if [ ! -f ~/ip.sh ] then echo "#!/bin/bash -ip -4 rule add from 127.0.0.1/8 iif lo table 100 -ip -6 rule add from ::1/128 iif lo table 100 +ip rule add from 127.0.0.1/8 iif lo table 100 ip route add local 0.0.0.0/0 dev lo table 100 +ip -6 rule add from ::1/128 iif lo table 100 ip -6 route add local ::/0 dev lo table 100" > ~/ip.sh chmod +x ~/ip.sh fi @@ -39966,13 +40171,16 @@ $HOME/ip.sh" > /etc/rc.local if [[ $(systemctl is-active rc-local) == "inactive" ]] then - systemctl enbale rc-local - systemctl start rc-local + systemctl enable rc-local || true + if ! grep -q 'iif lo lookup 100' < <(ip rule list) + then + systemctl start rc-local || true + fi fi Println "$info mmproxy-$mmproxy_name 设置成功\n" ;; - 20) + 17) DepInstall curl DNSCRYPT_ROOT=$(dirname ~/dnscrypt-*/dnscrypt-proxy | sort | tail -1) @@ -40030,7 +40238,12 @@ $HOME/ip.sh" > /etc/rc.local exit 0 fi - arch=$(uname -m) + ArchCheck + + if [ "$arch" != "arm64" ] && grep -q "arm" <<< "$arch" + then + arch="arm" + fi if dnscrypt_version=$(curl -s -Lm 20 "$FFMPEG_MIRROR_LINK/dnscrypt.json" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') then @@ -40137,14 +40350,48 @@ $HOME/ip.sh" > /etc/rc.local Println "$error 无法连接服务器, 请稍后再试\n" fi ;; - 21) + 18) NginxUpdateCFIBMip ;; + 19) + NginxDeleteDomain + ;; + 20) + if [[ ! -x $(command -v pdf2htmlEX) ]] + then + echo + AskIfContinue n "`gettext \"因为是编译 pdf2htmlEX, 耗时会很长, 是否继续\"`" + Pdf2htmlInstall + Println "$info pdf2htmlEX 安装完成, 输入 source /etc/profile 可立即使用\n" + else + Println "$error pdf2htmlEX 已存在!\n" + fi + ;; + 21) + if [[ ! -x $(command -v tesseract) ]] + then + DepsCheck + echo + if [ "$release" == "ubu" ] + then + add-apt-repository ppa:alex-p/tesseract-ocr -y + AptUpdate + apt-get -y install tesseract + elif [ "$release" == "deb" ] + then + Println "$info 参考 https://notesalexp.org/tesseract-ocr/ ...\n" + else + Println "$info 参考 https://tesseract-ocr.github.io/tessdoc/Home.html ...\n" + fi + else + Println "$error tesseract 已存在!\n" + fi + ;; *) Println "$error $i18n_input_correct_number [1-21]\n" ;; esac exit 0 -elif [ "$self" == "v2" ] || [ "$self" == "v2.sh" ] || [ "$self" == "V2.sh" ] || [ "$self" == "x" ] || [ "$self" == "x.sh" ] || [ "$self" == "xray.sh" ] +elif [ "$self" == "v2" ] || [ "$self" == "V2" ] || [ "$self" == "x" ] || [ "$self" == "xray" ] then ShFileCheck [ ! -d "$IPTV_ROOT" ] && JQ_FILE="/usr/local/bin/jq" @@ -40152,19 +40399,19 @@ then v2ray_name="v2ray" tls_name="TLS" - if [ "$self" == "x" ] || [ "$self" == "x.sh" ] || [ "$self" == "xray.sh" ] + if [ "$self" == "x" ] || [ "$self" == "xray" ] then v2ray_sh="x" v2ray_name="xray" tls_name="XTLS" V2_FILE="/usr/local/bin/x" V2_LINK="https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh" - V2_LINK_BACKUP="$FFMPEG_MIRROR_LINK/xray_install-release.sh" + V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xray_install-release.sh" V2CTL_FILE="/usr/local/bin/xray" V2_CONFIG="/usr/local/etc/xray/config.json" elif [ -d "/etc/v2ray/" ] then - systemctl disable v2ray.service --now > /dev/null 2> /dev/null || true + systemctl disable v2ray --now > /dev/null 2> /dev/null || true rm -rf /usr/bin/v2ray/ rm -f /etc/systemd/system/v2ray.service rm -f /lib/systemd/system/v2ray.service @@ -40192,7 +40439,7 @@ then case $* in "e") [ ! -e "$V2_CONFIG" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 - vim "$V2_CONFIG" && exit 0 + editor "$V2_CONFIG" && exit 0 ;; *) ;; @@ -40383,7 +40630,7 @@ then ;; esac exit 0 -elif [ "$self" == "cx" ] || [ "$self" == "cx.sh" ] +elif [ "$self" == "cx" ] then [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 @@ -40519,7 +40766,7 @@ ${green}8.${normal} 浏览频道 ;; esac exit 0 -elif [ "$self" == "arm" ] || [ "$self" == "arm.sh" ] +elif [ "$self" == "arm" ] then if [[ ! -x $(command -v armbian-config) ]] then @@ -40799,7 +41046,7 @@ method=ignore" > /etc/NetworkManager/system-connections/armbian.nmconnection exit 1 fi - if [[ $(systemctl is-active docker.service) == "inactive" ]] + if [[ $(systemctl is-active docker) == "inactive" ]] then systemctl start docker fi @@ -41453,7 +41700,7 @@ config interface 'lan' ;; esac exit 0 -elif [ "$self" == "pve" ] || [ "$self" == "pve.sh" ] +elif [ "$self" == "pve" ] then if [[ ! -x $(command -v pveum) ]] then @@ -41470,9 +41717,9 @@ then ${green}1.${normal} 设置 apt 源 ${green}2.${normal} 设置 vimrc ${green}3.${normal} 设置 显示器 -———————————— ${green}4.${normal} 查看 温度 / 风扇 ${green}5.${normal} 设置 风扇 +———————————— ${green}6.${normal} 安装 升级 dnscrypt ${green}7.${normal} 安装 qemu-guest-agent ${green}8.${normal} 安装 openwrt-v2ray @@ -41607,15 +41854,15 @@ then fi echo - nbfc_options=( '查看状态' '风扇切换为手动控制' '设置风扇转速' '搜索配置' '应用配置' ) - inquirer list_input "选择操作" nbfc_options nbfc_option + nbfc_options=( '查看状态' '切换风扇手动/自动控制' '设置风扇转速' '搜索配置' '应用配置' ) + inquirer list_input_index "选择操作" nbfc_options nbfc_options_index cd /opt/nbfc - if [ "$nbfc_option" == "查看状态" ] + if [ "$nbfc_options_index" -eq 0 ] then mono nbfc.exe status --all - elif [ "$nbfc_option" == "风扇切换为手动控制" ] + elif [ "$nbfc_options_index" -eq 1 ] then echo inquirer text_input "输入寄存器地址, 比如 0x93: " register_address "$i18n_cancel" @@ -41634,7 +41881,7 @@ then fi Println "$tip 不一定写入成功, 请自行检查\n" - elif [ "$nbfc_option" == "设置风扇转速" ] + elif [ "$nbfc_options_index" -eq 2 ] then Println "$tip 请确保风扇处于手动控制状态" echo @@ -41667,10 +41914,10 @@ then Println "$tip 操作成功\n" fi - elif [ "$nbfc_option" == "搜索配置" ] + elif [ "$nbfc_options_index" -eq 3 ] then mono nbfc.exe config -r - elif [ "$nbfc_option" == "应用配置" ] + elif [ "$nbfc_options_index" -eq 4 ] then echo inquirer text_input "输入配置名称, 比如: Acer Aspire 5745G" config_name "$i18n_cancel" @@ -42613,13 +42860,17 @@ then ;; "e") [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 - vim "$CHANNELS_FILE" && exit 0 + editor "$CHANNELS_FILE" && exit 0 ;; "ee") [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 GetDefault [ -z "$d_sync_file" ] && Println "$error sync_file 未设置, 请检查 !\n" && exit 1 - vim "${d_sync_file%% *}" && exit 0 + echo + edit_options=($d_sync_file) + inquirer list_input "选择修改的文件" edit_options edit_option + editor "$edit_option" + exit 0 ;; "d") [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 @@ -42758,7 +43009,7 @@ then #Println "输入镜像网站链接(比如: $FFMPEG_MIRROR_LINK)" #read -p "$i18n_default_cancel" FFMPEG_LINK - #[ -z "$FFMPEG_LINK" ] && echo "$i18n_canceled...\n" && exit 1 + #[ -z "$FFMPEG_LINK" ] && Println "$i18n_canceled...\n" && exit 1 #sed -i "s+https://johnvansickle.com/ffmpeg/\(builds\|releases\)/\(.*\).tar.xz\"+$FFMPEG_LINK/\1/\2.tar.xz\"+g" "$FFMPEG_MIRROR_ROOT/index.html" sed -i "s+https://johnvansickle.com/ffmpeg/\(builds\|releases\)/\(.*\).tar.xz\"+\1/\2.tar.xz\"+g" "$FFMPEG_MIRROR_ROOT/index.html" @@ -42820,48 +43071,48 @@ then Println "$error jq 下载出错, 无法连接 github ?" fi + archs=( 32 64 arm32-v5 arm32-v6 arm32-v7a arm64-v8a s390x) + if v2ray_ver=$(curl -s -m 30 "https://api.github.com/repos/v2fly/v2ray-core/releases/latest" | $JQ_FILE -r '.tag_name') then - if [ ! -e "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip" ] || [ ! -e "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip" ] - then - Println "$info 下载 v2ray $v2ray_ver ..." - mkdir -p "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/" - if curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-64.zip" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip_tmp" \ - && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-32.zip" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip_tmp" \ - && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-64.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip.dgst_tmp" \ - && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-32.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip.dgst_tmp" + mkdir -p "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/" + for arch in "${archs[@]}" + do + if [ ! -e "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip" ] then - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip" - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip" - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip.dgst" - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip.dgst" - else - Println "$error v2ray $v2ray_ver 下载出错, 无法连接 github ?" + Println "$info 下载 v2ray-linux-$arch $v2ray_ver ..." + if curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-$arch.zip" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip_tmp" \ + && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-$arch.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip.dgst_tmp" + then + mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip" + mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip.dgst" + else + Println "$error v2ray-linux-$arch $v2ray_ver 下载出错, 无法连接 github ?" + fi fi - fi + done else Println "$error v2ray $v2ray_ver 下载出错, 无法连接 github ?" fi if xray_ver=$(curl -s -m 30 "https://api.github.com/repos/XTLS/Xray-core/releases/latest" | $JQ_FILE -r '.tag_name') then - if [ ! -e "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip" ] || [ ! -e "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip" ] - then - Println "$info 下载 xray $xray_ver ..." - mkdir -p "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/" - if curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-64.zip" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip_tmp" \ - && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-32.zip" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip_tmp" \ - && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-64.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip.dgst_tmp" \ - && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-32.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip.dgst_tmp" + mkdir -p "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/" + for arch in "${archs[@]}" + do + if [ ! -e "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip" ] then - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip" - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip" - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip.dgst" - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip.dgst" - else - Println "$error xray $xray_ver 下载出错, 无法连接 github ?" + Println "$info 下载 Xray-linux-$arch $xray_ver ..." + if curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-$arch.zip" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip_tmp" \ + && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-$arch.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip.dgst_tmp" + then + mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip" + mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip.dgst" + else + Println "$error Xray-linux-$arch $xray_ver 下载出错, 无法连接 github ?" + fi fi - fi + done else Println "$error xray $xray_ver 下载出错, 无法连接 github ?" fi @@ -42917,7 +43168,7 @@ then if dnscrypt_ver=$(curl -s -m 30 "https://api.github.com/repos/DNSCrypt/dnscrypt-proxy/releases/latest" | $JQ_FILE -r '.tag_name') then - archs=( arm64 x86_64 ) + archs=( arm arm64 i386 x86_64 ) for arch in "${archs[@]}" do @@ -43218,6 +43469,40 @@ then sed -i "0,/sh_debug=.*/s//sh_debug=${2:-1}/" "$SH_FILE" exit 0 ;; + "ed"|"editor") + ReleaseCheck + DepInstall vim + if [ "$release" == "rpm" ] + then + alternatives --config editor + else + update-alternatives --config editor + fi + exit 0 + ;; + "a") + if [[ ! -x $(command -v readlink) ]] + then + Println "$error 系统不支持 readlink\n" + exit 1 + fi + echo + inquirer text_input "输入自定义命令名称" name "$i18n_cancel" + ExitOnCancel name + if command -v "$name" > /dev/null + then + Println "$error 命令已经存在\n" + exit 1 + fi + echo + alternative_options=( nginx openresty xray v2ray armbian "proxmox ve" + "ibm cloud foundry" "cloudflare partner,workers" ffmpeg ) + inquirer list_input_index "选择执行的脚本" alternative_options alternative_options_index + commands=( NX_FILE OR_FILE X_FILE V2_FILE ARM_FILE PVE_FILE IBM_FILE CF_FILE SH_FILE ) + ln -s ${!commands[alternative_options_index]} /usr/bin/$name + Println "$info 自定义命令 $name 添加成功\n" + exit 0 + ;; "c") to_locale=${2:-} new_locale="" diff --git a/i18n/iptv.sh.pot b/i18n/iptv.sh.pot index 88bc77e..6271482 100644 --- a/i18n/iptv.sh.pot +++ b/i18n/iptv.sh.pot @@ -1,4 +1,4 @@ -# Locale en For iptv.sh v1.80.5 - ONE Click Script. +# Locale en For iptv.sh v1.80.9 - ONE Click Script # Copyright (C) GPL Version 3 License # This file is distributed under the same license as the iptv.sh package. # MTimer https://github.com/woniuzfb/iptv @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: iptv.sh 1.80.4\n" "Report-Msgid-Bugs-To: tg @woniuzfb\n" -"POT-Creation-Date: 2021-05-20 07:51+0000\n" +"POT-Creation-Date: 2021-06-15 10:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,1187 +17,1199 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../docs/iptv.sh:212 +#: ../docs/iptv.sh:242 #, sh-format msgid "$info Installing $dependency, it takes awhile..." msgstr "" -#: ../docs/iptv.sh:223 ../docs/iptv.sh:233 +#: ../docs/iptv.sh:253 ../docs/iptv.sh:263 #, sh-format msgid "$info $dependency installation succeed" msgstr "" -#: ../docs/iptv.sh:225 ../docs/iptv.sh:235 +#: ../docs/iptv.sh:255 ../docs/iptv.sh:265 #, sh-format msgid "$error $dependency installation failed" msgstr "" -#: ../docs/iptv.sh:253 ../docs/iptv.sh:265 +#: ../docs/iptv.sh:283 ../docs/iptv.sh:295 #, sh-format msgid "${green}Succeed!${normal}" msgstr "" -#: ../docs/iptv.sh:267 +#: ../docs/iptv.sh:297 #, sh-format msgid "${red}Failed! Please try again later!${normal}" msgstr "" -#: ../docs/iptv.sh:276 +#: ../docs/iptv.sh:306 msgid "yes" msgstr "" -#: ../docs/iptv.sh:277 +#: ../docs/iptv.sh:307 msgid "no" msgstr "" -#: ../docs/iptv.sh:278 +#: ../docs/iptv.sh:308 msgid "cancel" msgstr "" -#: ../docs/iptv.sh:279 +#: ../docs/iptv.sh:309 msgid "canceled" msgstr "" -#: ../docs/iptv.sh:280 +#: ../docs/iptv.sh:310 msgid "(default: cancel): " msgstr "" -#: ../docs/iptv.sh:281 +#: ../docs/iptv.sh:311 msgid "please input correct No." msgstr "" -#: ../docs/iptv.sh:282 +#: ../docs/iptv.sh:312 msgid "please input correct number" msgstr "" -#: ../docs/iptv.sh:283 +#: ../docs/iptv.sh:313 msgid "[INFO]" msgstr "" -#: ../docs/iptv.sh:284 +#: ../docs/iptv.sh:314 msgid "[ERROR]" msgstr "" -#: ../docs/iptv.sh:285 +#: ../docs/iptv.sh:315 msgid "[NOTE]" msgstr "" -#: ../docs/iptv.sh:290 ../docs/iptv.sh:315 +#: ../docs/iptv.sh:320 ../docs/iptv.sh:345 msgid "video delay" msgstr "" -#: ../docs/iptv.sh:291 ../docs/iptv.sh:316 +#: ../docs/iptv.sh:321 ../docs/iptv.sh:346 msgid "audio delay" msgstr "" -#: ../docs/iptv.sh:292 ../docs/iptv.sh:317 +#: ../docs/iptv.sh:322 ../docs/iptv.sh:347 msgid "seconds" msgstr "" -#: ../docs/iptv.sh:293 ../docs/iptv.sh:318 ../docs/iptv.sh:6102 -#: ../docs/iptv.sh:6114 ../docs/iptv.sh:6142 +#: ../docs/iptv.sh:323 ../docs/iptv.sh:348 ../docs/iptv.sh:6201 +#: ../docs/iptv.sh:6213 ../docs/iptv.sh:6241 msgid "not set" msgstr "" -#: ../docs/iptv.sh:294 ../docs/iptv.sh:319 +#: ../docs/iptv.sh:324 ../docs/iptv.sh:349 msgid " constant:NO" msgstr "" -#: ../docs/iptv.sh:295 ../docs/iptv.sh:320 +#: ../docs/iptv.sh:325 ../docs/iptv.sh:350 msgid " constant:YES" msgstr "" -#: ../docs/iptv.sh:296 ../docs/iptv.sh:321 +#: ../docs/iptv.sh:326 ../docs/iptv.sh:351 msgid "resolution" msgstr "" -#: ../docs/iptv.sh:297 ../docs/iptv.sh:322 +#: ../docs/iptv.sh:327 ../docs/iptv.sh:352 msgid "bitrates" msgstr "" -#: ../docs/iptv.sh:298 ../docs/iptv.sh:323 +#: ../docs/iptv.sh:328 ../docs/iptv.sh:353 msgid "original" msgstr "" -#: ../docs/iptv.sh:299 +#: ../docs/iptv.sh:329 msgid "proxy" msgstr "" -#: ../docs/iptv.sh:300 ../docs/iptv.sh:324 +#: ../docs/iptv.sh:330 ../docs/iptv.sh:354 msgid "running" msgstr "" -#: ../docs/iptv.sh:301 ../docs/iptv.sh:325 +#: ../docs/iptv.sh:331 ../docs/iptv.sh:355 msgid "stopped" msgstr "" -#: ../docs/iptv.sh:302 +#: ../docs/iptv.sh:332 msgid "PID" msgstr "" -#: ../docs/iptv.sh:303 +#: ../docs/iptv.sh:333 msgid "status" msgstr "" -#: ../docs/iptv.sh:304 +#: ../docs/iptv.sh:334 msgid "channel name" msgstr "" -#: ../docs/iptv.sh:305 +#: ../docs/iptv.sh:335 msgid "codec" msgstr "" -#: ../docs/iptv.sh:306 ../docs/iptv.sh:346 +#: ../docs/iptv.sh:336 ../docs/iptv.sh:376 msgid "delay" msgstr "" -#: ../docs/iptv.sh:307 +#: ../docs/iptv.sh:337 msgid "video quality" msgstr "" -#: ../docs/iptv.sh:308 +#: ../docs/iptv.sh:338 msgid "source" msgstr "" -#: ../docs/iptv.sh:309 +#: ../docs/iptv.sh:339 msgid "playlist file" msgstr "" -#: ../docs/iptv.sh:310 +#: ../docs/iptv.sh:340 msgid "FLV push link" msgstr "" -#: ../docs/iptv.sh:311 +#: ../docs/iptv.sh:341 msgid "FLV pull link" msgstr "" -#: ../docs/iptv.sh:314 +#: ../docs/iptv.sh:344 msgid "Channel changed, try again!" msgstr "" -#: ../docs/iptv.sh:326 +#: ../docs/iptv.sh:356 msgid "sync not set" msgstr "" -#: ../docs/iptv.sh:327 +#: ../docs/iptv.sh:357 msgid "sync disabled" msgstr "" -#: ../docs/iptv.sh:330 +#: ../docs/iptv.sh:360 msgid "playlist name" msgstr "" -#: ../docs/iptv.sh:331 +#: ../docs/iptv.sh:361 msgid "playlist link" msgstr "" -#: ../docs/iptv.sh:332 +#: ../docs/iptv.sh:362 msgid "segment directory" msgstr "" -#: ../docs/iptv.sh:333 +#: ../docs/iptv.sh:363 msgid "segment name" msgstr "" -#: ../docs/iptv.sh:334 +#: ../docs/iptv.sh:364 msgid "segment duration" msgstr "" -#: ../docs/iptv.sh:335 +#: ../docs/iptv.sh:365 msgid "segments count" msgstr "" -#: ../docs/iptv.sh:336 +#: ../docs/iptv.sh:366 msgid "encrypt" msgstr "" -#: ../docs/iptv.sh:337 +#: ../docs/iptv.sh:367 msgid "keyinfo name" msgstr "" -#: ../docs/iptv.sh:338 +#: ../docs/iptv.sh:368 msgid "key name" msgstr "" -#: ../docs/iptv.sh:339 +#: ../docs/iptv.sh:369 msgid "live" msgstr "" -#: ../docs/iptv.sh:340 +#: ../docs/iptv.sh:370 msgid "xtream codes proxy" msgstr "" -#: ../docs/iptv.sh:341 +#: ../docs/iptv.sh:371 msgid "user agent" msgstr "" -#: ../docs/iptv.sh:342 +#: ../docs/iptv.sh:372 msgid "headers" msgstr "" -#: ../docs/iptv.sh:343 +#: ../docs/iptv.sh:373 msgid "cookies" msgstr "" -#: ../docs/iptv.sh:344 +#: ../docs/iptv.sh:374 msgid "video codec" msgstr "" -#: ../docs/iptv.sh:345 +#: ../docs/iptv.sh:375 msgid "audio codec" msgstr "" -#: ../docs/iptv.sh:347 +#: ../docs/iptv.sh:377 msgid "input flags" msgstr "" -#: ../docs/iptv.sh:348 +#: ../docs/iptv.sh:378 msgid "output flags" msgstr "" -#: ../docs/iptv.sh:349 +#: ../docs/iptv.sh:379 msgid "none" msgstr "" -#: ../docs/iptv.sh:407 +#: ../docs/iptv.sh:437 #, sh-format msgid "${red}[ERROR]${normal} MUST BE ROOT, TRY${green} sudo su ${normal}" msgstr "" -#: ../docs/iptv.sh:456 +#: ../docs/iptv.sh:486 msgid "Checking dependencies, it takes awhile" msgstr "" -#: ../docs/iptv.sh:475 ../docs/iptv.sh:486 ../docs/iptv.sh:496 -#: ../docs/iptv.sh:506 ../docs/iptv.sh:521 ../docs/iptv.sh:532 -#: ../docs/iptv.sh:542 +#: ../docs/iptv.sh:505 ../docs/iptv.sh:516 ../docs/iptv.sh:526 +#: ../docs/iptv.sh:536 ../docs/iptv.sh:551 ../docs/iptv.sh:562 +#: ../docs/iptv.sh:572 #, sh-format msgid "$info dependency $depend installation succeed" msgstr "" -#: ../docs/iptv.sh:477 ../docs/iptv.sh:488 ../docs/iptv.sh:498 -#: ../docs/iptv.sh:508 ../docs/iptv.sh:523 ../docs/iptv.sh:534 -#: ../docs/iptv.sh:544 +#: ../docs/iptv.sh:507 ../docs/iptv.sh:518 ../docs/iptv.sh:528 +#: ../docs/iptv.sh:538 ../docs/iptv.sh:553 ../docs/iptv.sh:564 +#: ../docs/iptv.sh:574 #, sh-format msgid "$error dependency $depend installation failed" msgstr "" -#: ../docs/iptv.sh:856 +#: ../docs/iptv.sh:886 msgid "(Press Select, Confirm)" msgstr "" -#: ../docs/iptv.sh:1046 +#: ../docs/iptv.sh:1076 msgid "(Use up/down arrow to select)" msgstr "" -#: ../docs/iptv.sh:1305 +#: ../docs/iptv.sh:1335 msgid "input verification failed" msgstr "" -#: ../docs/iptv.sh:1390 ../docs/iptv.sh:1397 +#: ../docs/iptv.sh:1420 ../docs/iptv.sh:1427 #, sh-format msgid "$info Script downloading completed" msgstr "" -#: ../docs/iptv.sh:1392 ../docs/iptv.sh:1435 +#: ../docs/iptv.sh:1422 ../docs/iptv.sh:1465 #, sh-format msgid "$error can't connect Github! Trying backup link..." msgstr "" -#: ../docs/iptv.sh:1399 +#: ../docs/iptv.sh:1429 #, sh-format msgid "$error can't connect backup link! Script downloading failed, try again later" msgstr "" -#: ../docs/iptv.sh:1422 +#: ../docs/iptv.sh:1452 #, sh-format msgid "$info updating script $sh_name..." msgstr "" -#: ../docs/iptv.sh:1428 ../docs/iptv.sh:1440 +#: ../docs/iptv.sh:1458 ../docs/iptv.sh:1470 #, sh-format msgid "$info script $sh_name updating completed" msgstr "" -#: ../docs/iptv.sh:1447 +#: ../docs/iptv.sh:1477 #, sh-format msgid "$error can't connect backup link! Script $sh_name updating failed, try again later" msgstr "" -#: ../docs/iptv.sh:1458 +#: ../docs/iptv.sh:1488 #, sh-format msgid "$info Installing, please wait..." msgstr "" -#: ../docs/iptv.sh:1500 +#: ../docs/iptv.sh:1530 #, sh-format msgid "$info Installing python3 ..." msgstr "" -#: ../docs/iptv.sh:1553 +#: ../docs/iptv.sh:1641 #, sh-format msgid "$info Start downloading/installing FFmpeg..." msgstr "" -#: ../docs/iptv.sh:1566 +#: ../docs/iptv.sh:1662 #, sh-format msgid "$error FFmpeg downloading failed!" msgstr "" -#: ../docs/iptv.sh:1569 +#: ../docs/iptv.sh:1667 #, sh-format msgid "$error FFmpeg decompression failed!" msgstr "" -#: ../docs/iptv.sh:1571 +#: ../docs/iptv.sh:1669 #, sh-format msgid "$info FFmpeg installed" msgstr "" -#: ../docs/iptv.sh:1573 +#: ../docs/iptv.sh:1671 #, sh-format msgid "$info FFmpeg already installed" msgstr "" -#: ../docs/iptv.sh:1583 +#: ../docs/iptv.sh:1681 #, sh-format msgid "$error not support centos" msgstr "" -#: ../docs/iptv.sh:1588 +#: ../docs/iptv.sh:1686 msgid "Choose tls" msgstr "" -#: ../docs/iptv.sh:2387 +#: ../docs/iptv.sh:2485 #, sh-format msgid "$info FFmpeg compiled successfully" msgstr "" -#: ../docs/iptv.sh:2396 ../docs/iptv.sh:2416 +#: ../docs/iptv.sh:2495 ../docs/iptv.sh:2515 #, sh-format msgid "$info Start downloading/installing JQ..." msgstr "" -#: ../docs/iptv.sh:2413 ../docs/iptv.sh:2430 +#: ../docs/iptv.sh:2512 ../docs/iptv.sh:2528 #, sh-format msgid "$info JQ installed" msgstr "" -#: ../docs/iptv.sh:2433 +#: ../docs/iptv.sh:2531 #, sh-format msgid "$error JQ downloading failed, try again!" msgstr "" -#: ../docs/iptv.sh:2436 ../docs/iptv.sh:2611 +#: ../docs/iptv.sh:2534 ../docs/iptv.sh:2710 #, sh-format msgid "$error Can't connect server, try again later!" msgstr "" -#: ../docs/iptv.sh:2439 +#: ../docs/iptv.sh:2537 #, sh-format msgid "$info JQ already installed" msgstr "" -#: ../docs/iptv.sh:2447 +#: ../docs/iptv.sh:2545 #, sh-format msgid "$error directory already exists, uninstall first..." msgstr "" -#: ../docs/iptv.sh:2550 +#: ../docs/iptv.sh:2649 #, sh-format msgid "$info Installation completed" msgstr "" -#: ../docs/iptv.sh:2556 ../docs/iptv.sh:2597 ../docs/iptv.sh:6151 +#: ../docs/iptv.sh:2655 ../docs/iptv.sh:2696 ../docs/iptv.sh:6250 #, sh-format msgid "$error Not installed!" msgstr "" -#: ../docs/iptv.sh:2559 +#: ../docs/iptv.sh:2658 msgid "Do you confirm deleting this script and files with it" msgstr "" -#: ../docs/iptv.sh:2592 +#: ../docs/iptv.sh:2691 #, sh-format msgid "$info Uninstallation completed" msgstr "" -#: ../docs/iptv.sh:2618 +#: ../docs/iptv.sh:2717 msgid "monitoring need to be stopped, do you want to continue" msgstr "" -#: ../docs/iptv.sh:2626 +#: ../docs/iptv.sh:2725 msgid "You already have the latest version of FFmpeg, do you want to reinstall it" msgstr "" -#: ../docs/iptv.sh:2642 +#: ../docs/iptv.sh:2741 msgid "updating FFmpeg" msgstr "" -#: ../docs/iptv.sh:2650 +#: ../docs/iptv.sh:2749 #, sh-format msgid "script updated to the latest version [ ${green}$sh_new_ver${normal} ] ! (cmd: tv)" msgstr "" -#: ../docs/iptv.sh:2655 +#: ../docs/iptv.sh:2754 #, sh-format msgid "$info Installing youtube-dl..." msgstr "" -#: ../docs/iptv.sh:2680 +#: ../docs/iptv.sh:2779 #, sh-format msgid "$info openssl installation completed" msgstr "" -#: ../docs/iptv.sh:2701 +#: ../docs/iptv.sh:2800 #, sh-format msgid "$info magick installation completed" msgstr "" -#: ../docs/iptv.sh:3035 +#: ../docs/iptv.sh:3134 #, sh-format msgid "$FILE JQ fd 200 failed" msgstr "" -#: ../docs/iptv.sh:3432 ../docs/iptv.sh:3463 +#: ../docs/iptv.sh:3531 ../docs/iptv.sh:3562 #, sh-format msgid "$error wrong sync settings" msgstr "" -#: ../docs/iptv.sh:3533 +#: ../docs/iptv.sh:3632 #, sh-format msgid "$info channel [ $chnl_channel_name ] sync succeed..." msgstr "" -#: ../docs/iptv.sh:6101 +#: ../docs/iptv.sh:6200 msgid "random name" msgstr "" -#: ../docs/iptv.sh:6103 +#: ../docs/iptv.sh:6202 msgid "same as playlist name" msgstr "" -#: ../docs/iptv.sh:6108 +#: ../docs/iptv.sh:6207 #, sh-format msgid "video delay $d_video_shift seconds" msgstr "" -#: ../docs/iptv.sh:6112 +#: ../docs/iptv.sh:6211 #, sh-format msgid "audio delay $d_audio_shift seconds" msgstr "" -#: ../docs/iptv.sh:6247 +#: ../docs/iptv.sh:6346 #, sh-format msgid "$error no channels found!" msgstr "" -#: ../docs/iptv.sh:6351 +#: ../docs/iptv.sh:6450 msgid "Starting all stopped channels" msgstr "" -#: ../docs/iptv.sh:6352 +#: ../docs/iptv.sh:6451 msgid "Stopping all running channels" msgstr "" -#: ../docs/iptv.sh:6355 +#: ../docs/iptv.sh:6454 msgid "Restart all running channels" msgstr "" -#: ../docs/iptv.sh:6359 +#: ../docs/iptv.sh:6458 msgid "channels count" msgstr "" -#: ../docs/iptv.sh:6597 +#: ../docs/iptv.sh:6696 #, sh-format msgid "Channel [$chnl_channel_name] configuration" msgstr "" -#: ../docs/iptv.sh:6650 +#: ../docs/iptv.sh:6749 #, sh-format msgid "$tip multiple numbers separated with space e.g. 5 7 9-11" msgstr "" -#: ../docs/iptv.sh:6651 +#: ../docs/iptv.sh:6750 msgid "Input numbers(default: cancel): " msgstr "" -#: ../docs/iptv.sh:6673 +#: ../docs/iptv.sh:6772 #, sh-format msgid "$error stopped channel not found" msgstr "" -#: ../docs/iptv.sh:6687 ../docs/iptv.sh:6702 +#: ../docs/iptv.sh:6786 ../docs/iptv.sh:6801 #, sh-format msgid "$error running channel not found" msgstr "" -#: ../docs/iptv.sh:6718 ../docs/iptv.sh:6728 +#: ../docs/iptv.sh:6817 ../docs/iptv.sh:6827 #, sh-format msgid "$error wrong number" msgstr "" -#: ../docs/iptv.sh:6761 ../docs/iptv.sh:7186 -msgid "" +#: ../docs/iptv.sh:6860 ../docs/iptv.sh:7285 +msgid "stream link:" msgstr "" -#: ../docs/iptv.sh:6767 +#: ../docs/iptv.sh:6866 #, sh-format -msgid "" +msgid "reorder stream links of channel [ $chnl_channel_name ]" msgstr "" -#: ../docs/iptv.sh:6784 -msgid "" +#: ../docs/iptv.sh:6883 +msgid "input new order numbers" msgstr "" -#: ../docs/iptv.sh:6785 -msgid "" +#: ../docs/iptv.sh:6884 +msgid "example" msgstr "" -#: ../docs/iptv.sh:6795 ../docs/iptv.sh:6811 +#: ../docs/iptv.sh:6894 ../docs/iptv.sh:6910 #, sh-format -msgid "" +msgid "$error input error" msgstr "" -#: ../docs/iptv.sh:6818 +#: ../docs/iptv.sh:6917 #, sh-format -msgid "" +msgid "$tip It can be local path and also multiple links, separated by space" msgstr "" -#: ../docs/iptv.sh:6819 -msgid "" +#: ../docs/iptv.sh:6918 +msgid "Please input stream link( mpegts / hls / flv / youtube ...): " msgstr "" -#: ../docs/iptv.sh:6893 ../docs/iptv.sh:16491 ../docs/iptv.sh:21730 -#: ../docs/iptv.sh:22043 ../docs/iptv.sh:24155 ../docs/iptv.sh:24194 -#: ../docs/iptv.sh:24581 ../docs/iptv.sh:27831 ../docs/iptv.sh:28851 -#: ../docs/iptv.sh:30267 ../docs/iptv.sh:30292 ../docs/iptv.sh:30396 -#: ../docs/iptv.sh:32748 ../docs/iptv.sh:35211 ../docs/iptv.sh:38751 -#: ../docs/iptv.sh:38799 ../docs/iptv.sh:39013 ../docs/iptv.sh:39549 -#: ../docs/iptv.sh:39695 ../docs/iptv.sh:40258 ../docs/iptv.sh:40403 -#: ../docs/iptv.sh:40556 ../docs/iptv.sh:41489 +#: ../docs/iptv.sh:6992 ../docs/iptv.sh:16589 ../docs/iptv.sh:21833 +#: ../docs/iptv.sh:22155 ../docs/iptv.sh:24271 ../docs/iptv.sh:24310 +#: ../docs/iptv.sh:24697 ../docs/iptv.sh:28022 ../docs/iptv.sh:29042 +#: ../docs/iptv.sh:30458 ../docs/iptv.sh:30483 ../docs/iptv.sh:30587 +#: ../docs/iptv.sh:32939 ../docs/iptv.sh:35402 ../docs/iptv.sh:38942 +#: ../docs/iptv.sh:38990 ../docs/iptv.sh:39204 ../docs/iptv.sh:39763 +#: ../docs/iptv.sh:39921 ../docs/iptv.sh:40505 ../docs/iptv.sh:40650 +#: ../docs/iptv.sh:40803 ../docs/iptv.sh:41736 msgid "Input No." msgstr "" -#: ../docs/iptv.sh:6917 +#: ../docs/iptv.sh:7016 #, sh-format -msgid "" +msgid "$error Can't parse $link" msgstr "" -#: ../docs/iptv.sh:6922 +#: ../docs/iptv.sh:7021 #, sh-format -msgid "" +msgid "$info Parsing youtube link..." msgstr "" -#: ../docs/iptv.sh:7033 ../docs/iptv.sh:7107 ../docs/iptv.sh:42109 +#: ../docs/iptv.sh:7132 ../docs/iptv.sh:7206 ../docs/iptv.sh:42356 msgid "Installing openssl" msgstr "" -#: ../docs/iptv.sh:7036 ../docs/iptv.sh:7110 +#: ../docs/iptv.sh:7135 ../docs/iptv.sh:7209 #, sh-format -msgid "" +msgid "$info Parsing 4gtv link ..." msgstr "" -#: ../docs/iptv.sh:7097 ../docs/iptv.sh:7165 +#: ../docs/iptv.sh:7196 ../docs/iptv.sh:7264 #, sh-format -msgid "" +msgid "$error Can't connect 4gtv !" msgstr "" -#: ../docs/iptv.sh:7171 +#: ../docs/iptv.sh:7270 #, sh-format -msgid "" +msgid "$error Channel unavailable or this server ip not allowed!" msgstr "" -#: ../docs/iptv.sh:9419 ../docs/iptv.sh:9620 ../docs/iptv.sh:9627 +#: ../docs/iptv.sh:9518 ../docs/iptv.sh:9719 ../docs/iptv.sh:9726 msgid "Channel is running, stopping now" msgstr "" -#: ../docs/iptv.sh:13718 +#: ../docs/iptv.sh:13816 msgid "pdf2htmlEX required. Compiling pdf2htmlEX, it takes awhile. Do you want to continue" msgstr "" -#: ../docs/iptv.sh:16153 +#: ../docs/iptv.sh:16251 msgid "Installing imgcat" msgstr "" -#: ../docs/iptv.sh:16270 ../docs/iptv.sh:16302 +#: ../docs/iptv.sh:16368 ../docs/iptv.sh:16400 msgid "Registration is complete, login now" msgstr "" -#: ../docs/iptv.sh:16364 +#: ../docs/iptv.sh:16462 msgid "Register an account" msgstr "" -#: ../docs/iptv.sh:16419 +#: ../docs/iptv.sh:16517 msgid "old link detected. Do you want to replace it with this new link" msgstr "" -#: ../docs/iptv.sh:21305 +#: ../docs/iptv.sh:21403 #, sh-format msgid "Are you sure you want to permanently remove all $nginx_name files" msgstr "" -#: ../docs/iptv.sh:21330 +#: ../docs/iptv.sh:21428 #, sh-format msgid "Recompiling $nginx_name" msgstr "" -#: ../docs/iptv.sh:21352 +#: ../docs/iptv.sh:21450 #, sh-format msgid "$nginx_name is running, stopping now" msgstr "" -#: ../docs/iptv.sh:21357 +#: ../docs/iptv.sh:21455 #, sh-format msgid "$nginx_name is stopped, starting now" msgstr "" -#: ../docs/iptv.sh:25051 ../docs/iptv.sh:30841 +#: ../docs/iptv.sh:25245 ../docs/iptv.sh:31032 msgid "override old installation" msgstr "" -#: ../docs/iptv.sh:27800 +#: ../docs/iptv.sh:27994 msgid "print QR code" msgstr "" -#: ../docs/iptv.sh:30104 +#: ../docs/iptv.sh:30295 msgid "reset all traffic stats" msgstr "" -#: ../docs/iptv.sh:32233 +#: ../docs/iptv.sh:32424 msgid "Deleting this domain anyway. Also remove domain from official website to add this domain again" msgstr "" -#: ../docs/iptv.sh:32281 +#: ../docs/iptv.sh:32472 msgid "Do you want to delete all domains added with this CFP" msgstr "" -#: ../docs/iptv.sh:32539 +#: ../docs/iptv.sh:32730 msgid "Updating this token" msgstr "" -#: ../docs/iptv.sh:33055 +#: ../docs/iptv.sh:33246 msgid "directory already exits, add anyway" msgstr "" -#: ../docs/iptv.sh:36836 +#: ../docs/iptv.sh:37027 msgid "Deleting IBM CF CLI, do you want to continue" msgstr "" -#: ../docs/iptv.sh:38745 ../docs/iptv.sh:38780 +#: ../docs/iptv.sh:38936 ../docs/iptv.sh:38971 msgid "VIP manager" msgstr "" -#: ../docs/iptv.sh:38747 ../docs/iptv.sh:38785 +#: ../docs/iptv.sh:38938 ../docs/iptv.sh:38976 msgid "View VIP channels" msgstr "" -#: ../docs/iptv.sh:38748 +#: ../docs/iptv.sh:38939 msgid "Input VIP auth code" msgstr "" -#: ../docs/iptv.sh:38750 ../docs/iptv.sh:38798 +#: ../docs/iptv.sh:38941 ../docs/iptv.sh:38989 #, sh-format msgid "$tip cmd: h => HLS manager, f => FLV manager" msgstr "" -#: ../docs/iptv.sh:38774 +#: ../docs/iptv.sh:38965 #, sh-format msgid "$error Intall first with cmd: tv" msgstr "" -#: ../docs/iptv.sh:38782 +#: ../docs/iptv.sh:38973 msgid "View VIP user" msgstr "" -#: ../docs/iptv.sh:38783 +#: ../docs/iptv.sh:38974 msgid "Add VIP user" msgstr "" -#: ../docs/iptv.sh:38784 +#: ../docs/iptv.sh:38975 msgid "Config VIP user" msgstr "" -#: ../docs/iptv.sh:38786 +#: ../docs/iptv.sh:38977 msgid "Add VIP channel" msgstr "" -#: ../docs/iptv.sh:38787 -msgid "" +#: ../docs/iptv.sh:38978 +msgid "Deploy VIP channel" msgstr "" -#: ../docs/iptv.sh:38788 +#: ../docs/iptv.sh:38979 msgid "Config VIP channel" msgstr "" -#: ../docs/iptv.sh:38789 +#: ../docs/iptv.sh:38980 msgid "View VIP server" msgstr "" -#: ../docs/iptv.sh:38790 +#: ../docs/iptv.sh:38981 msgid "Add VIP server" msgstr "" -#: ../docs/iptv.sh:38791 +#: ../docs/iptv.sh:38982 msgid "Config VIP server" msgstr "" -#: ../docs/iptv.sh:38792 +#: ../docs/iptv.sh:38983 msgid "Delete VIP user" msgstr "" -#: ../docs/iptv.sh:38793 +#: ../docs/iptv.sh:38984 msgid "Delete VIP channel" msgstr "" -#: ../docs/iptv.sh:38794 +#: ../docs/iptv.sh:38985 msgid "Delete VIP server" msgstr "" -#: ../docs/iptv.sh:38795 +#: ../docs/iptv.sh:38986 msgid "Enable VIP" msgstr "" -#: ../docs/iptv.sh:38796 +#: ../docs/iptv.sh:38987 msgid "Disable VIP" msgstr "" -#: ../docs/iptv.sh:38883 +#: ../docs/iptv.sh:39074 msgid "Installing vim-plug and overriding ~/.vimrc, do you want to continue" msgstr "" -#: ../docs/iptv.sh:38987 +#: ../docs/iptv.sh:39178 msgid "cmd: f => FLV manager, v => VIP manager" msgstr "" -#: ../docs/iptv.sh:38991 +#: ../docs/iptv.sh:39182 msgid "cmd: h => HLS manager, v => VIP manager" msgstr "" -#: ../docs/iptv.sh:38996 +#: ../docs/iptv.sh:39187 msgid "IPTV manager" msgstr "" -#: ../docs/iptv.sh:38998 +#: ../docs/iptv.sh:39189 msgid "Install" msgstr "" -#: ../docs/iptv.sh:38999 +#: ../docs/iptv.sh:39190 msgid "Uninstall" msgstr "" -#: ../docs/iptv.sh:39000 +#: ../docs/iptv.sh:39191 msgid "Update" msgstr "" -#: ../docs/iptv.sh:39002 +#: ../docs/iptv.sh:39193 msgid "View channel" msgstr "" -#: ../docs/iptv.sh:39003 +#: ../docs/iptv.sh:39194 msgid "Add channel" msgstr "" -#: ../docs/iptv.sh:39004 +#: ../docs/iptv.sh:39195 msgid "Config channel" msgstr "" -#: ../docs/iptv.sh:39005 +#: ../docs/iptv.sh:39196 msgid "Toggle channel" msgstr "" -#: ../docs/iptv.sh:39006 +#: ../docs/iptv.sh:39197 msgid "Restart channel" msgstr "" -#: ../docs/iptv.sh:39007 +#: ../docs/iptv.sh:39198 msgid "View logs" msgstr "" -#: ../docs/iptv.sh:39008 +#: ../docs/iptv.sh:39199 msgid "Delete channel" msgstr "" -#: ../docs/iptv.sh:39009 +#: ../docs/iptv.sh:39200 msgid "Config default" msgstr "" -#: ../docs/iptv.sh:39011 +#: ../docs/iptv.sh:39202 #, sh-format msgid "$tip now: ${green}$title${normal} manager" msgstr "" -#: ../docs/iptv.sh:39057 +#: ../docs/iptv.sh:39248 msgid "Usage: tv -i [input stream] [-s segment length(s)] [-o output directory name] [-c segments count] [-b bitrates] [-p HLS playlist name] [-C] [-l] [-P http proxy]" msgstr "" -#: ../docs/iptv.sh:39058 +#: ../docs/iptv.sh:39249 msgid " -i input stream(support mpegts / hls / flv / youtube ...)" msgstr "" -#: ../docs/iptv.sh:39059 +#: ../docs/iptv.sh:39250 msgid "can be path to local video" msgstr "" -#: ../docs/iptv.sh:39060 +#: ../docs/iptv.sh:39251 msgid "you can input multiple stream links, separate with space" msgstr "" -#: ../docs/iptv.sh:39061 +#: ../docs/iptv.sh:39252 msgid " -s segment length(s)(default: 6)" msgstr "" -#: ../docs/iptv.sh:39062 +#: ../docs/iptv.sh:39253 msgid " -o output directory name(default: random)" msgstr "" -#: ../docs/iptv.sh:39064 +#: ../docs/iptv.sh:39255 msgid " -l not live stream, in this case it can't be monitored nor set segments number(default: no)" msgstr "" -#: ../docs/iptv.sh:39065 +#: ../docs/iptv.sh:39256 msgid " -P http proxy for FFmpeg, apply to http input stream(default: no)" msgstr "" -#: ../docs/iptv.sh:39067 +#: ../docs/iptv.sh:39258 msgid " -p HLS playlist name(default: random)" msgstr "" -#: ../docs/iptv.sh:39068 +#: ../docs/iptv.sh:39259 msgid " -c segments number in HLS playlist(default: 5)" msgstr "" -#: ../docs/iptv.sh:39069 +#: ../docs/iptv.sh:39260 msgid " -S sub directory for segments(default: no)" msgstr "" -#: ../docs/iptv.sh:39070 +#: ../docs/iptv.sh:39261 msgid " -t segments name(prefix)(default: same as playlist name)" msgstr "" -#: ../docs/iptv.sh:39071 +#: ../docs/iptv.sh:39262 msgid " -a audio codec(default: aac) (e.g. copy)" msgstr "" -#: ../docs/iptv.sh:39072 +#: ../docs/iptv.sh:39263 msgid " -v video codec(default: libx264) (e.g. copy)" msgstr "" -#: ../docs/iptv.sh:39073 +#: ../docs/iptv.sh:39264 msgid " -f video or audio delay(e.g. v_3 video delay 3 seconds, a_2 audio delay 2 seconds)" msgstr "" -#: ../docs/iptv.sh:39074 +#: ../docs/iptv.sh:39265 msgid " -d convert dvb teletext, options: text,ass (default: no)" msgstr "" -#: ../docs/iptv.sh:39075 +#: ../docs/iptv.sh:39266 msgid " -q crf value(precedence over bitrates)(0-63 greater number worse video qualit), multiple crf can be separated by comma" msgstr "" -#: ../docs/iptv.sh:39076 +#: ../docs/iptv.sh:39267 msgid "(default: crf not set)" msgstr "" -#: ../docs/iptv.sh:39077 +#: ../docs/iptv.sh:39268 msgid " -b bitrates of the output video(kb/s)(default: 900-1280x720)" msgstr "" -#: ../docs/iptv.sh:39078 +#: ../docs/iptv.sh:39269 msgid "If crf is set, bitrates value apply to -maxrate -bufsize" msgstr "" -#: ../docs/iptv.sh:39079 +#: ../docs/iptv.sh:39270 msgid "If crf is not set you can continue to set const option of FFmpeg" msgstr "" -#: ../docs/iptv.sh:39080 +#: ../docs/iptv.sh:39271 msgid "multiple bitrates can be separated by comma(in this case adaptive stream will be created)" msgstr "" -#: ../docs/iptv.sh:39081 +#: ../docs/iptv.sh:39272 msgid "you can set video dimensions(e.g. -b 800-640x360,1000-960x540,1500-1280x720)" msgstr "" -#: ../docs/iptv.sh:39082 +#: ../docs/iptv.sh:39273 msgid "input omit to skip this option" msgstr "" -#: ../docs/iptv.sh:39083 +#: ../docs/iptv.sh:39274 msgid " -C constant bitrates(only work if crf not set)(default: no)" msgstr "" -#: ../docs/iptv.sh:39084 +#: ../docs/iptv.sh:39275 msgid " -e encrypt segments(default: no)" msgstr "" -#: ../docs/iptv.sh:39085 +#: ../docs/iptv.sh:39276 msgid " -K Key name(default: random)" msgstr "" -#: ../docs/iptv.sh:39086 +#: ../docs/iptv.sh:39277 msgid " -z channel name(default: same as playlist name)" msgstr "" -#: ../docs/iptv.sh:39087 +#: ../docs/iptv.sh:39278 msgid "push FLV stream instead of HLS" msgstr "" -#: ../docs/iptv.sh:39088 +#: ../docs/iptv.sh:39279 msgid " -k push stream kind, e.g. -k flv" msgstr "" -#: ../docs/iptv.sh:39089 +#: ../docs/iptv.sh:39280 msgid " -H push h265 stream(default: no)" msgstr "" -#: ../docs/iptv.sh:39090 +#: ../docs/iptv.sh:39281 msgid " -T push address, e.g. rtmp://127.0.0.1/flv/xxx" msgstr "" -#: ../docs/iptv.sh:39091 +#: ../docs/iptv.sh:39282 msgid " -L pull(play) address(default: omit). e.g. http://domain.com/flv?app=flv&stream=xxx" msgstr "" -#: ../docs/iptv.sh:39092 +#: ../docs/iptv.sh:39283 msgid " -m more input flags for FFmpeg" msgstr "" -#: ../docs/iptv.sh:39093 ../docs/iptv.sh:39099 +#: ../docs/iptv.sh:39284 ../docs/iptv.sh:39290 msgid "default:" msgstr "" -#: ../docs/iptv.sh:39096 +#: ../docs/iptv.sh:39287 msgid "If it's HLS input stream, remove -reconnect_at_eof 1" msgstr "" -#: ../docs/iptv.sh:39097 +#: ../docs/iptv.sh:39288 msgid "If it's rtmp or local video, remove -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2000" msgstr "" -#: ../docs/iptv.sh:39098 +#: ../docs/iptv.sh:39289 msgid " -n output flags for FFmpeg, input omit to skip this option" msgstr "" -#: ../docs/iptv.sh:39101 +#: ../docs/iptv.sh:39292 msgid "Examples:" msgstr "" -#: ../docs/iptv.sh:39102 +#: ../docs/iptv.sh:39293 msgid "Use crf to control video quality:" msgstr "" -#: ../docs/iptv.sh:39103 +#: ../docs/iptv.sh:39294 msgid "tv -i http://xxx.com/xxx.ts -s 6 -o hbo1 -p hbo1 -q 15 -b 1500-1280x720 -z 'hbo stream 1'" msgstr "" -#: ../docs/iptv.sh:39104 +#: ../docs/iptv.sh:39295 msgid "Use bitrates to control video quality[default]:" msgstr "" -#: ../docs/iptv.sh:39105 +#: ../docs/iptv.sh:39296 msgid "tv -i http://xxx.com/xxx.ts -s 6 -o hbo2 -p hbo2 -b 900-1280x720 -z 'hbo stream 2'" msgstr "" -#: ../docs/iptv.sh:39106 +#: ../docs/iptv.sh:39297 msgid "If no need converting:" msgstr "" -#: ../docs/iptv.sh:39107 +#: ../docs/iptv.sh:39298 msgid "Push FLV instead of HLS:" msgstr "" -#: ../docs/iptv.sh:39110 +#: ../docs/iptv.sh:39301 msgid "Shortcuts:" msgstr "" -#: ../docs/iptv.sh:39111 +#: ../docs/iptv.sh:39302 msgid "tv # open HLS manager" msgstr "" -#: ../docs/iptv.sh:39112 +#: ../docs/iptv.sh:39303 msgid "tv l # list all running channels" msgstr "" -#: ../docs/iptv.sh:39113 +#: ../docs/iptv.sh:39304 msgid "tv d # add demo channels" msgstr "" -#: ../docs/iptv.sh:39114 +#: ../docs/iptv.sh:39305 msgid "tv e # mannual editing channels.json" msgstr "" -#: ../docs/iptv.sh:39115 +#: ../docs/iptv.sh:39306 +msgid "tv ee # mannual editing sync_file" +msgstr "" + +#: ../docs/iptv.sh:39307 msgid "tv f # open FLV manager" msgstr "" -#: ../docs/iptv.sh:39116 +#: ../docs/iptv.sh:39308 msgid "tv v # open VIP manager" msgstr "" -#: ../docs/iptv.sh:39117 +#: ../docs/iptv.sh:39309 msgid "tv m # start monitoring" msgstr "" -#: ../docs/iptv.sh:39118 +#: ../docs/iptv.sh:39310 msgid "tv m l [lines count] # view monitoring log" msgstr "" -#: ../docs/iptv.sh:39119 +#: ../docs/iptv.sh:39311 msgid "tv m s # stop monitoring" msgstr "" -#: ../docs/iptv.sh:39120 +#: ../docs/iptv.sh:39312 msgid "tv s # tv guide manager" msgstr "" -#: ../docs/iptv.sh:39121 +#: ../docs/iptv.sh:39313 msgid "tv 4g # 4gtv manager" msgstr "" -#: ../docs/iptv.sh:39122 +#: ../docs/iptv.sh:39314 msgid "tv FFmpeg # create mirror for FFmpeg" msgstr "" -#: ../docs/iptv.sh:39123 +#: ../docs/iptv.sh:39315 msgid "tv debug 1/0 # enable/disable debug" msgstr "" -#: ../docs/iptv.sh:39125 +#: ../docs/iptv.sh:39317 msgid "cx # open xtream codes accoutns/channels manager" msgstr "" -#: ../docs/iptv.sh:39127 +#: ../docs/iptv.sh:39319 msgid "v2 # open v2ray manager" msgstr "" -#: ../docs/iptv.sh:39128 +#: ../docs/iptv.sh:39320 msgid "v2 e # mannual editing config.json" msgstr "" -#: ../docs/iptv.sh:39130 +#: ../docs/iptv.sh:39322 msgid "x # open xray manager" msgstr "" -#: ../docs/iptv.sh:39131 +#: ../docs/iptv.sh:39323 msgid "x e # mannual editing config.json" msgstr "" -#: ../docs/iptv.sh:39133 +#: ../docs/iptv.sh:39325 msgid "nx # open nginx manager" msgstr "" -#: ../docs/iptv.sh:39135 +#: ../docs/iptv.sh:39327 msgid "or # open openresty manager" msgstr "" -#: ../docs/iptv.sh:39137 +#: ../docs/iptv.sh:39329 msgid "cf # open cloudflare partner / workers manager" msgstr "" -#: ../docs/iptv.sh:39138 +#: ../docs/iptv.sh:39330 msgid "cf w # open cloudflare workers manager" msgstr "" -#: ../docs/iptv.sh:39140 +#: ../docs/iptv.sh:39332 msgid "ibm # open IBM Cloud Foundry manager" msgstr "" -#: ../docs/iptv.sh:39141 +#: ../docs/iptv.sh:39333 msgid "ibm v2 # open ibm v2ray app manager" msgstr "" -#: ../docs/iptv.sh:39142 +#: ../docs/iptv.sh:39334 msgid "ibm x # open ibm xray app manager" msgstr "" -#: ../docs/iptv.sh:39144 +#: ../docs/iptv.sh:39336 msgid "arm # open Armbian manager" msgstr "" -#: ../docs/iptv.sh:39146 +#: ../docs/iptv.sh:39338 msgid "pve # open Proxmox VE manager" msgstr "" -#: ../docs/iptv.sh:39148 +#: ../docs/iptv.sh:39340 +msgid "tv ed # choose default editor" +msgstr "" + +#: ../docs/iptv.sh:39342 +msgid "tv a # creating custom commands" +msgstr "" + +#: ../docs/iptv.sh:39344 msgid "tv c change/update language" msgstr "" -#: ../docs/iptv.sh:39158 +#: ../docs/iptv.sh:39354 msgid "Installation was not completed, do you want to reinstall" msgstr "" -#: ../docs/iptv.sh:39558 +#: ../docs/iptv.sh:39772 msgid "Compiling openresty, it takes awhile. Do you want to continue" msgstr "" -#: ../docs/iptv.sh:39704 +#: ../docs/iptv.sh:39930 msgid "Compiling nginx, it takes awhile. Do you want to continue" msgstr "" -#: ../docs/iptv.sh:39770 -msgid "Compiling pdf2htmlEX, it takes awhile. Do you want to continue" -msgstr "" - -#: ../docs/iptv.sh:39804 +#: ../docs/iptv.sh:39996 msgid "postfix exits. Do you want to reconfig smtp" msgstr "" -#: ../docs/iptv.sh:39995 ../docs/iptv.sh:41398 ../docs/iptv.sh:42043 +#: ../docs/iptv.sh:40203 ../docs/iptv.sh:41645 ../docs/iptv.sh:42290 msgid "Disable edns0" msgstr "" -#: ../docs/iptv.sh:40002 ../docs/iptv.sh:41406 ../docs/iptv.sh:42050 +#: ../docs/iptv.sh:40210 ../docs/iptv.sh:41653 ../docs/iptv.sh:42297 msgid "Enable edns0" msgstr "" #: ../docs/iptv.sh:40363 +msgid "Compiling pdf2htmlEX, it takes awhile. Do you want to continue" +msgstr "" + +#: ../docs/iptv.sh:40610 #, sh-format msgid "$v2ray_name is running, stopping now" msgstr "" -#: ../docs/iptv.sh:40368 +#: ../docs/iptv.sh:40615 #, sh-format msgid "$v2ray_name is stopped, starting now" msgstr "" -#: ../docs/iptv.sh:40417 +#: ../docs/iptv.sh:40664 msgid "It takes awhile. Do you want to continue" msgstr "" -#: ../docs/iptv.sh:40564 +#: ../docs/iptv.sh:40811 msgid "This is for PHICOMM n1. It need to be run after apt upgrade. Do you want to continue" msgstr "" -#: ../docs/iptv.sh:40615 ../docs/iptv.sh:40747 ../docs/iptv.sh:40879 -#: ../docs/iptv.sh:41441 +#: ../docs/iptv.sh:40862 ../docs/iptv.sh:40994 ../docs/iptv.sh:41126 +#: ../docs/iptv.sh:41688 msgid "Do you want to continue" msgstr "" -#: ../docs/iptv.sh:41576 +#: ../docs/iptv.sh:41823 msgid "Installing mono, it takes awhile. Do you want to continue" msgstr "" -#: ../docs/iptv.sh:43298 +#: ../docs/iptv.sh:43583 msgid "Not installed, start installing now" msgstr "" -#: ../docs/iptv.sh:43314 +#: ../docs/iptv.sh:43599 #, sh-format msgid "Use proxy $d_proxy: " msgstr "" -#: ../docs/iptv.sh:43340 +#: ../docs/iptv.sh:43625 #, sh-format msgid "Use xtream codes proxy $d_xc_proxy: " msgstr "" -#: ../docs/iptv.sh:43518 +#: ../docs/iptv.sh:43803 #, sh-format msgid "$error push link not set..." msgstr "" -#: ../docs/iptv.sh:43539 +#: ../docs/iptv.sh:43824 #, sh-format msgid "$info channel added successfully" msgstr "" diff --git a/i18n/make-pot.sh b/i18n/make-pot.sh index eb0d826..82223c2 100755 --- a/i18n/make-pot.sh +++ b/i18n/make-pot.sh @@ -41,11 +41,20 @@ PACKAGE_NAME=iptv.sh # iptv.sh, v2.sh, x.sh, nx.sh, or.sh, cf.sh, ibm.sh, arm.sh PACKAGE_POT_LANGUAGE=$1 # en, zh_CN PACKAGE_PO_LANGUAGE=$2 # ru, de ... +XSRC=../docs/$PACKAGE_NAME + +PACKAGE_VERSION=$(grep 'sh_ver="' < $XSRC |awk -F "=" '{print $NF}'|$GSED 's/\"//g'|head -1) +PACKAGE_TITLE="Locale ${PACKAGE_PO_LANGUAGE:-en} For $PACKAGE_NAME v$PACKAGE_VERSION - ONE Click Script" + if [ "$1" == "b" ] && [ -e "po/$PACKAGE_NAME-en.po" ] then awk '$1 == "msgstr" { s=$0; sub(/msgstr/, "msgid", s); print s; print "msgstr \"\""; next } $1 == "msgid" { next } 1' "po/$PACKAGE_NAME-en.po" > "$PACKAGE_NAME.pot" + $GSED -i ' + { + s~Locale .*$~'"$PACKAGE_TITLE"'~ + }' "$PACKAGE_NAME.pot" exit 0 fi @@ -72,10 +81,6 @@ IENC=UTF-8 # Output encoding OENC=UTF-8 -XSRC=../docs/$PACKAGE_NAME - -PACKAGE_VERSION=$(grep 'sh_ver="' < $XSRC |awk -F "=" '{print $NF}'|$GSED 's/\"//g'|head -1) -PACKAGE_TITLE="Locale $PACKAGE_PO_LANGUAGE For $PACKAGE_NAME v$PACKAGE_VERSION - ONE Click Script" PACKAGE_COPYRIGHT="GPL Version 3 License" PACKAGE_FIRST_POT_AUTHOR="MTimer https://github.com/woniuzfb/iptv" PACKAGE_POT_CREATION_TZ="UTC" diff --git a/i18n/po/iptv.sh-en.mo b/i18n/po/iptv.sh-en.mo index 0c36dd1b6072757fa7c7aefb1c7f2bc9ddc06a65..2dd1c062fa9c0ab9f320f59b2ba183525d1f7a29 100644 GIT binary patch delta 6965 zcmZA533yc18OHH5AVSzeAS8tKk{}=i#DuVeKoXPy1r$V-s*_|Op-Cnt6Og4H6-C)Z zGJtFaSq0Pt85IQywzPFaiiMU%Dz+t?&|0i$X`%N2&ONq1-Y4Ju&N+8E%XjW1@SE2? zXWsDyKW%-}8pF}fV@yXp-^7?Q%9~=;YD{swG1Ku8Ou`SbGk$>&V9R#KOvc$b4By5< zcnwEjN`f(i@exeMmvADU!EVL`P0#k6q+tRM#3R@pzrh*Uxq~r@xBxS8GxouY*aKTL z>Mb|~yW%+FU~>DX{Yr7#?ildpF$T-e1_Z;nV#&#G#P^#f{fHmMJ8?L zqXtxN&%cfi^%JP)T(RvjRMMy?;{?pc4BThiuVR-V4ZR&kiQ`Z+528BQWqltt)62*` zCYEWo!Tv~J<}T#N%;JMpHA^rKx7+$bY)kzVw#LtG`wa|ghVk@9*`#1BPC*SMA4#Km z4t3ogWRc9TP!IYuYEN864J?6*9E`eey0rwgqRUVN-i=E2yGg7+W%Df`>M)6Q&ciIc z9mCigt8pmC+~RgP0d@T&sE*d*XnYm5QeUA4+>wj8)eJ-^XWRNl>`8q)@?(zip^1KlEwCLYqp*9B zf;#SJ9cmqe%Hd?xO!BZ7E<#q@RNyrH7$@Pax4JW(k6Pj_sQao=yZ+QthB7 z6dX-KOOuVt(a)?K(V_k(s>8FWO?Msj8nq%X>L3v{(BZZ|1)Ea$qxQ;tdww12`IV?W zb_{u5(EN!)6b)BV5BwIji`(;U(HQ$9gEzzQW}Jx{c_Hq>708&(K=RQXv#oyA^$Sr0 zT7;VDv-bR6jMn>qfPx0_u08Rwt$&IdX&q|DH>}aDr#kA2>Y%SR%{t7QZp}iyev?s4 zKMTj>5}Zc=<_{DaV&B`CEvDcgoP~q&1yqOUP&2Q^hp;g_E(>Sj1l*6As8?q>j6n_X zBs+_QFDJgX>VKc^UQKlgJoMowW-)Qv-;NphGHL~`AOj7W>lC!PS`Kj^*vmQ)m8%TYjPsBUZmMt?et{Z5 z@=*78#9-7?`%vvqS<6x1BU`YW$CwvUDL=+T67~K!rKZi)2i4JdOvi1Qj5Vl^+l+8m zCM*fsDmmKz&oTzk`j5!;!vBIja3Q{ur;IgA+$GksyU)3Vi9ASCHQi<}A)d z&nWlCd8iIHpx#or1jKrYw{7 z*NHteX!Cr48u=elBfM#hJEK0>nR*5$Vh-y1#i$vr$0U3WyWttsfNr4f>wTx2sw~tm zp#`Y+b$7D<4uu2u#2Hl1uc8K!c$d3`<51TXq6Y9RYNoGZC;SNY`d&f}z!~eBiOj{! zMqV7V4{ybKR6lKkS?+}+tv=L}Ek)8}cA#=zi|QzDoV!Q*qjEh1m9kRg67w`R$KPQy zynr|3CF_^inEEx;$^|_nusem0sE*Q67nGoO_k3G_3AMyw?24yRGrfk*vGWA?J@1Vz zsQ0&ywobx$+8;!%+#Kw!_rIKiW>$sM@jPmC4fv7!#j^y}(Pr#|M^OX&3u<%5PIL#> z2X);7nrzgF^RWq*+V+L0 z&9ewKlg+5zeHhse=4)(#>3j|9dteL>$H#C4R-qhCW#JV8SXTw&d4 z-GevLegGTd+xQ^9gW7Ce?sGS32I~Iln1-`(0R9}c!lzIvs>L?=6~<$eAk$8u;Gi0Y zpmKA!H5>Kd5>##W*;34dY$58{ngnI73 zQG25CL;Q-y5jdFsO*sXP=osq4&#)I>M$IVxVYlN{RL(}Caybz_NXjF}2tFfki>*J2 zorwj+V%zqiwJA5gKsl(K{FJC68tG{qEJWn!Yt6);5x3j==XjbpL>wh15YG`h{zh~n z`l!OO$R+Z5C!h1aSEm?^a761B`;BAS7=w1d5iI^VpJ&3YYm z1c@s|4A<<#zY_h37SzAOLSi^^O;^55VJ|U}(4k$eLA+NY;P5BJ!*g;efzf^_eFtL?* zlsHG|2ou`niK=ik=Kg%Q_`lBvlwKi9-AuXdui4Xo$FanGTQA4u!~t8s#X1LD@$h0C zW83sPIJR7ZdP_DEYl)FW5wVm=A~p~n5A%PC!fawH@gDJeLhrqwxI{co%pm3xD~T70 zS;P=x6!F7j6Ak*l_=xzHh$i9~SVz>+f;da$5iwf-G~!3Z&0M781DD9Z3I0gA8=?Q6 z{Sx0Go*~{MbTp?u1A9hl?#E7BzF_?|{)s3c2HUn+?mIy_c#w}~RL0>Q_GCj05%=1< z_?oy#Br-*?>dtyJK;}ZoqRsqx?JKA4DawgwXM} zHpR2VP}Mk|A|58X5WT{k;>sJxytut)^K$k0{e>_A>^~%cH)w{cfj&wfI z+E-HIFLCOsLe)?0tY5vpuCg*5=#teStuE42ZuP^_()h)khrr)tA=lRP5W!XM^ zp3|WNU6;nKth{(=XU)3Gx)&GIW8Hzu>Z&J`ozUUl6T(9iTQ-XKI&~FQwTCO}p59ws zvEkxdOR85LzIbRyD6_|kG+(Y$|Jah6Wqaxmt*fipQTz7Vx~f%7#RTR!KA%&wWLfpn z-4~Bk)U1BXDV&=-Q31)s(+dbMU$P ztp}?Qt_;`r+v;gpz3Yk4;*|YS-<=y09+3LEr|JK$?HTGfEV025Cmfg7)YH6X?Y`O# zPu9G=mHR^p0~WMew7d53e&^n?lN`6BaQT3zqmt9TMLhyevA3ku=Vr!qbJx~Ak>f8a z^5q2F1r4_v+1-A<(E38zLGh<5@oQ+A8@<{1^&6d z+^(U%qrx%nQ}c_8%K}cM9KJB>lLo1i=sCY=mfL}LhV%b?eRuA=gz2=>70!5S6X%D#>EW10rHeR&nYeT=J>)XnemM} zdYvREr^M$CXb3rFr2&7TljAQemRo5iG#OE)`Wlc&0^i${#$nnn%y_L}=eB_?zJ&k>jdJ7q9XzJA6 z&A)fiknr`XpLr4{75KdL?XKJRPJfr|&?nQ*#}xVIk^=QoR92YnD=7`_yKi~x3}119 Re_kZxId0CvL#HqE{1*Z-9L@j$ delta 5843 zcmY+|34Bdg0>|<55Q!ip5wUx*1hEUTZ;99iC9yMArFL4&sPGuIGsPo=AXH1WCYDF- z`_NKL4O-h+Yia1H4n>Rh_kZ`~Gc)(&|Gwv(+;{KU?hP&;bRFC7@>~ncwZw1)xr`}+ zy@QN-lk$p!YBk1P*q9y|g=KLfmck6|h5NBH7K=2d5e~z8xB;8sEv%1GMU1I}y|5$B z!g9uV%tZ>LX?TToab!_rqH#U;#?x2^D;F~+5tFbgF2)LY7&9;nqi{}fW8!cl#^Y_Q zhS7{J6qBukurT*G6DXAC2MdrtX0!Daa!r$k^wb2DG={;L7*vPiQ9pkh-8cp7;2P|J z-(d?Z&vdDM2cnI|_>mcl8rfoGGRzmqtebCa{T@b8 zce#xT!${P5F{lopI2=R-?V4}-B2vX4zK>j3L;)Ii2zc}y$kaW>Ol8Uks^!W#Iqt(WDjiqtEk zI@A@pw@JnPxEk|dChEpJtw*e3RHISb$2J&eBcGoCG^b$J zqQ0;hgK-CHtq&t7nrm19A7CE*&9(=yvs4d5b+iO(#5Ju6sP8AEuHWA}*e~lp$~KI* zPDVXW(@|5Mj_q+DYN>*&7?TtGV{IIW^)Mal<9W=7A-ttD^5WPJ8)92b#}0TG6S=>s z%>vKE_fb6ztnOSm1hoee(2f03Bb|miZ$9cqi*0=k22=kOHFG{&KZ6CRUq+puWqpPo zjU*RaUIt+b=0k0|w@`ax5$bW8)MO0#?Wcg4K))p(TxjH7v74Y_@(s{>beh51ALB} zxtF#*XDsutH7XeE{GbLVQm>18+$N#ccnRtPCr}qSjoKR*(2dV98H;eTZaBg^5ereD zh3eQ!>n7_Vk1d=-y#eo7Un3jbMAmU0yLi;pr(hwRgmJjYdK`6QHOl-LhQ(~XDh5$+ zfGscqwO2f|C}^{IQD59--HTd+N>yY$Dq#Nf;<>zKWZkkY*hoWx06g4Bqu?ar0?Xe9R74-qA zH(v&J#ly%S6WPdV?}B}(k3%<}$41=WJf)x!)S_FwJxyO6k26pge2uz66nE8A(Hq&1 zW-e-k`%t_41Qy1NsHJ*@+9QRVIx|@hi&5{5yj0D2Eb5`KngZ_vvm3+lK1Se6WTTp} zX2!gMiP#>OqRzjA#WB3O^9rtxZt88ULy&!G=GyuJRL5?hIuIDo{Hw<`D3rohs1XlD zZJybv9bq_G6|6%2IjRHYTQL7o6q4AI zZXAVWa3S&lm~B`Nf3Sw|Y_fk$ELOr{s0*f{&O2hgk435HZ|VGfq5^8^hG0othFaZzz1`T(Ob19hWg7>G|%GxN&UtF?A! zG7dHHo*oM7c`9l%t-&D7L~W`a)}z*Q7)kq0)Y`v5ZQh7B&d8c$59<9;duA8veUXn* z={`}Y4zgOre5!M-~O}h$%aT{tW57?jI zLXG%W)OjV?$?P$YsYO9km5Az52h^qhL@a!Zh2Sf!ZVMPy;!H+Qc`oJ@+?7JM#BE9EiO9%wXi5W7c95yonltyOT4eRZwf( z5p|&r*bHx>o|>|qjTwX8Q5`&mJV53GYUzrxF|_2h(4(HFP|(!&!w`HM^~Eu$nMg%V z-Ar5m1oKnhY~61?iMeRMj5+Z-_Ql(%%@^Or*^Glw-%str{MVr{hlVgbh+3O-7>+kk zJ${0Ep7V8e>d{z$dJ}6B>VkbS6o;XfVlwJ_vrv!c64Z?CMP9DvX;6ZK z@b1o3*To7nw6ng4x^X&cD%YcyU<>L7U!&IeA~KuiDr&FPWM}GkKqFKKd!Vi}7~^m( zvYKWi*4OiIdO96wfI2Y=W3VTx=hIO)T!UJYOw^{`hc0YOmXOQj64^~s$$O+1(Q%dR zCt3m>^T=$nUH6Zo(1++)G~->srBVI=<9QT3@OVW@$BKqFn$y4%I@;9=UY#=&rkz+(p zMLV*Jv>`0Jf7u>j5!+_|K_Qd)$QNW7sX+#jbEE~SMgI3FPvu?P5Q}@gp%LL8J>`dq z7A*U?PGPmJ=$X*LX7L|e`D{r(CS!?q;60*4Z=Bm?B56c=kj*5H=+Lgr!48;(e^!HL z?{ubw>4D2LRNC02_6!j{rO>}G`N&eFRe>9*POn$J&4p{&#B|2)9wI`Y`IjmC6Rf{Z60k(wl$=$PZ+{~yR4l-HAHWFeVB29RCk z4mn7+kv&@fH596m#YD$aa)>0781f;>K9VU+CGAN;+t|b^D%o-_X6aA1JVsL2k(V?j zUy&2UzyFr2z;TB3^_TenG8}Bnfp~=UBz4I*L`PL}fecZF<2m_-bXA2TCpY~!y6nwI zs?l9F!R@}2zWYw*@_VbN-t$d~^aOfGmCo&JRyy3}o$1c>wTWt-!+WaiG~cdrK>^;Y zm1g@^#gxwDdlkFP}nHlYFDyGdT(u8!Xa`ObGwb9vwGx!xDu>$=OE(C3ObuJ3f;>ArJZe*l{^q1FHZ diff --git a/iptv.sh b/iptv.sh index ca3f5b9..9ef1017 100755 --- a/iptv.sh +++ b/iptv.sh @@ -1,17 +1,17 @@ #!/bin/bash -# FFmpeg / nginx / openresty / xray / v2ray / cloudflare partner,workers / ibm cf / armbian / proxmox Wrapper Script By MTimer +# FFmpeg / nginx / openresty / xray / v2ray / cloudflare partner,workers / ibm cf / armbian / proxmox ve Wrapper Script By MTimer # Copyright (C) 2019-2021 # Released under GPL Version 3 License set -euo pipefail -sh_ver="1.80.8" +sh_ver="1.80.9" sh_debug=0 export LANGUAGE= export LC_ALL= export LANG=en_US.UTF-8 SH_LINK="https://woniuzfb.github.io/iptv/iptv.sh" -SH_LINK_BACKUP="http://tv.epub.fun/iptv.sh" +SH_LINK_FALLBACK="http://tv.epub.fun/iptv.sh" SH_FILE="/usr/local/bin/tv" i18n_FILE="/usr/local/bin/tv-i18n" OR_FILE="/usr/local/bin/or" @@ -36,7 +36,7 @@ FFMPEG_LOG_ROOT="$IPTV_ROOT/ffmpeg" FFMPEG_MIRROR_LINK="http://pngquant.com/ffmpeg" V2_FILE="/usr/local/bin/v2" V2_LINK="https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh" -V2_LINK_BACKUP="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh" +V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh" V2CTL_FILE="/usr/local/bin/v2ctl" V2_CONFIG="/usr/local/etc/v2ray/config.json" X_FILE="/usr/local/bin/x" @@ -51,18 +51,18 @@ VIP_USERS_ROOT="$VIP_ROOT/users" C_ROOT="$IPTV_ROOT/c" MD5SUM_FILE="$C_ROOT/md5sum" MD5SUM_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/md5sum.c" -MD5SUM_LINK_BACKUP="$FFMPEG_MIRROR_LINK/md5sum.c" +MD5SUM_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/md5sum.c" CREATOR_FILE="$IPTV_ROOT/HLS-Stream-Creator.sh" CF_FILE="/usr/local/bin/cf" CF_CONFIG="$HOME/cloudflare.json" CF_WORKERS_ROOT="$HOME/workers" CF_WORKERS_FILE="$CF_WORKERS_ROOT/cloudflare_workers.py" CF_WORKERS_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/cloudflare_workers.py" -CF_WORKERS_LINK_BACKUP="$FFMPEG_MIRROR_LINK/cloudflare_workers.py" +CF_WORKERS_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/cloudflare_workers.py" STREAM_PROXY_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/stream_proxy.js" -STREAM_PROXY_LINK_BACKUP="$FFMPEG_MIRROR_LINK/stream_proxy.js" +STREAM_PROXY_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/stream_proxy.js" XTREAM_CODES_PROXY_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/xtream_codes_proxy.js" -XTREAM_CODES_PROXY_LINK_BACKUP="$FFMPEG_MIRROR_LINK/xtream_codes_proxy.js" +XTREAM_CODES_PROXY_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xtream_codes_proxy.js" IBM_FILE="/usr/local/bin/ibm" IBM_APPS_ROOT="$HOME/ibm_apps" IBM_CONFIG="$HOME/ibm.json" @@ -102,11 +102,11 @@ ReleaseCheck() then release="rpm" break - elif grep -Eqi "Ubuntu" < "$release_file" + elif grep -qi "Ubuntu" < "$release_file" then release="ubu" break - elif grep -Eqi "Debian" < "$release_file" + elif grep -qi "Debian" < "$release_file" then release="deb" break @@ -120,6 +120,36 @@ ReleaseCheck() fi } +ArchCheck() +{ + [ -n "${arch:-}" ] && return 0 + + arch=$(uname -m) + + if grep -Eqi "x86_64|amd64" <<< "$arch" + then + arch="x86_64" + elif grep -Eqi "i386|i686" <<< "$arch" + then + arch="i386" + elif grep -Eqi "aarch64|armv8" <<< "$arch" + then + arch="arm64" + elif grep -qi "armv7" <<< "$arch" + then + arch="armhf" + elif grep -qi "armv6" <<< "$arch" + then + arch="armv6l" + elif grep -qi "arm" <<< "$arch" + then + arch="armel" + elif grep -qi "s390" <<< "$arch" + then + arch="s390x" + fi +} + DebFixSources() { if [ "${deb_fix:-1}" -eq 1 ] @@ -1390,7 +1420,7 @@ ShFileCheck() Println "`eval_gettext \"\\\$info 脚本下载完成\"`" else Println "`eval_gettext \"\\\$error 无法连接到 Github ! 尝试备用链接...\"`" - if curl -s -Lm 30 "$SH_LINK_BACKUP" -o "${SH_FILE}_tmp" + if curl -s -Lm 30 "$SH_LINK_FALLBACK" -o "${SH_FILE}_tmp" then mv "${SH_FILE}_tmp" "$SH_FILE" chmod +x "$SH_FILE" @@ -1433,7 +1463,7 @@ ShFileUpdate() fi else Println "`eval_gettext \"\\\$error 无法连接到 Github ! 尝试备用链接...\"`" - if curl -s -Lm 30 "$SH_LINK_BACKUP" -o "${SH_FILE}_tmp" + if curl -s -Lm 30 "$SH_LINK_FALLBACK" -o "${SH_FILE}_tmp" then mv "${SH_FILE}_tmp" "$SH_FILE" chmod +x "$SH_FILE" @@ -1544,6 +1574,64 @@ CrossplaneInstall() pip3 install crossplane } +GoInstall() +{ + if [[ -x $(command -v go) ]] + then + go_version_list=($(go version)) + if [[ "${go_version_list[2]}" =~ ^go([0-9]+)\.([0-9]+)\. ]] && [ "${BASH_REMATCH[1]}" -ge 1 ] && [ "${BASH_REMATCH[2]}" -ge 11 ] + then + return 0 + fi + fi + + ArchCheck + + DepInstall curl + + go_version="" + + while IFS= read -r line + do + if [[ $line == *"goVersion = "* ]] + then + go_version=${line#*\"} + go_version=${go_version%\"*} + break + fi + done < <(curl -s -Lm 20 -H "User-Agent: $USER_AGENT_BROWSER" "https://golang.org/doc/install" 2> /dev/null) + + go_version=${go_version:-1.16.5} + + if [ "$arch" == "i386" ] + then + go_package="$go_version.linux-386.tar.gz" + elif [ "$arch" == "x86_64" ] + then + go_package="$go_version.linux-amd64.tar.gz" + elif [ "$arch" == "arm64" ] || [ "$arch" == "armv6l" ] + then + go_package="$go_version.linux-$arch.tar.gz" + else + DepInstall golang + return 0 + fi + + if ! curl -L https://golang.org/dl/$go_package -o ~/$go_package && ! curl -L https://gomirrors.org/dl/$go_package -o ~/$go_package + then + Println "$error 下载 golang 失败, 请稍后再试\n" + exit 1 + fi + + rm -rf /usr/local/go && tar -C /usr/local -xzf ~/$go_package + + if [[ ! -x $(command -v go) ]] + then + export PATH=$PATH:/usr/local/go/bin + echo "export PATH=\$PATH:/usr/local/go/bin" >> /etc/profile + fi +} + FFmpegInstall() { FFMPEG_ROOT=$(dirname "$IPTV_ROOT"/ffmpeg-git-*/ffmpeg) @@ -1551,19 +1639,29 @@ FFmpegInstall() if [ ! -e "$FFMPEG" ] then Println "`eval_gettext \"\\\$info 开始下载/安装 FFmpeg...\"`" - [ -z "${arch:-}" ] && arch=$(uname -m) - if [ "$arch" == "aarch64" ] - then - ffmpeg_package="ffmpeg-git-arm64-static.tar.xz" - elif grep -q 64 <<< "$arch" + ArchCheck + if [ "$arch" == "x86_64" ] then ffmpeg_package="ffmpeg-git-amd64-static.tar.xz" - else + elif [ "$arch" == "i386" ] + then + ffmpeg_package="ffmpeg-git-i686-static.tar.xz" + elif [ "$arch" == "armv6l" ] + then + ffmpeg_package="ffmpeg-git-armel-static.tar.xz" + elif grep -q "arm" <<< "$arch" + then ffmpeg_package="ffmpeg-git-$arch-static.tar.xz" + else + Println "$error FFmpeg 不支持当前系统\n" + exit 1 fi FFMPEG_PACKAGE_FILE="$IPTV_ROOT/$ffmpeg_package" - curl -L "$FFMPEG_MIRROR_LINK/builds/$ffmpeg_package" -o "$FFMPEG_PACKAGE_FILE" - [ ! -e "$FFMPEG_PACKAGE_FILE" ] && Println "`eval_gettext \"\\\$error FFmpeg 下载失败 !\"`" && exit 1 + if ! curl -L "$FFMPEG_MIRROR_LINK/builds/$ffmpeg_package" -o "$FFMPEG_PACKAGE_FILE" + then + Println "`eval_gettext \"\\\$error FFmpeg 下载失败 !\"`" + exit 1 + fi tar xJf "$FFMPEG_PACKAGE_FILE" -C "$IPTV_ROOT" && rm -f "${FFMPEG_PACKAGE_FILE:-notfound}" FFMPEG=$(dirname "$IPTV_ROOT"/ffmpeg-git-*/ffmpeg) [ ! -e "$FFMPEG" ] && Println "`eval_gettext \"\\\$error FFmpeg 解压失败 !\"`" && exit 1 @@ -2389,7 +2487,8 @@ Cflags: -I\${includedir} JQInstall() { - if [[ -x $(command -v armbian-config) ]] + ArchCheck + if grep -q "arm" <<< "$arch" then if ! /usr/local/bin/jq -V > /dev/null 2>&1 then @@ -2417,7 +2516,6 @@ JQInstall() #experimental# grep -Po '"tag_name": "jq-\K.*?(?=")' if jq_ver=$(curl -s -m 10 "$FFMPEG_MIRROR_LINK/jq.json" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') then - [ -z "${arch:-}" ] && arch=$(uname -m) if grep -q 64 <<< "$arch" then jq_package="jq-linux64" @@ -2547,6 +2645,7 @@ Install() }' > "$CHANNELS_FILE" ln -sf "$IPTV_ROOT"/ffmpeg-git-*/ff* /usr/local/bin/ + Println "`eval_gettext \"\\\$info 安装完成\"`\n" fi } @@ -9983,7 +10082,7 @@ EditChannelMenu() EditForSecurity ;; *) - echo "$i18n_input_correct_no...\n" && exit 1 + Println "$i18n_input_correct_no...\n" && exit 1 ;; esac @@ -10411,7 +10510,6 @@ StartChannel() chnl_cookies="" if [[ $chnl_stream_link =~ inews ]] then - chnl_audio_codec="aac" if [ "$chnl_video_codec" == "copy" ] && [[ ! $chnl_output_flags =~ -map ]] then chnl_output_flags="$chnl_output_flags -map 0:p:0" @@ -10427,7 +10525,7 @@ StartChannel() chnl_output_flags="$chnl_output_flags -vsync 0" fi fi - if [[ ! $chnl_output_flags =~ -ar ]] + if [ "$chnl_audio_codec" != "copy" ] && [[ ! $chnl_output_flags =~ -ar ]] then chnl_output_flags="$chnl_output_flags -ar 32000" fi @@ -11532,7 +11630,7 @@ StopChannel() rm -rf "$chnl_output_dir_root" rm -rf "$FFMPEG_LOG_ROOT/$chnl_pid.pid" else - kill "$chnl_pid" 2> /dev/null + kill "$chnl_pid" 2> /dev/null || true if ! flock -E 1 -w 30 -x "$FFMPEG_LOG_ROOT/$chnl_pid.pid" rm -rf "$FFMPEG_LOG_ROOT/$chnl_pid.pid" then MonitorError "频道[ $chnl_channel_name ] 进程 $chnl_pid 不存在" @@ -14208,7 +14306,7 @@ ScheduleSingteltv() program_sys_time=$(date -d "${program_times[program_i]}" +%s) [ -n "$schedule" ] && schedule="$schedule," schedule=$schedule'{ - "title":"'"${program_titles[program_i]}"'", + "title":"'"${program_titles[program_i]//\"/}"'", "time":"'"$program_time"'", "sys_time":"'"$program_sys_time"'" }' @@ -21241,7 +21339,7 @@ NginxInstall() nginx_package_name=${nginx_package_name%%.tar.gz*} break fi - done < <(curl -s -Lm 10 -H "User-Agent: $USER_AGENT_BROWSER" "https://nginx.org/en/download.html" 2> /dev/null) + done < <(curl -s -Lm 20 -H "User-Agent: $USER_AGENT_BROWSER" "https://nginx.org/en/download.html" 2> /dev/null) if [ ! -d "./$nginx_package_name" ] then @@ -21340,7 +21438,7 @@ NginxViewStatus() then Println "$error $nginx_name 未安装 !\n" else - systemctl status $nginx_name.service --no-pager + systemctl --no-pager status $nginx_name fi } @@ -21363,6 +21461,11 @@ NginxToggle() NginxRestart() { + if ! $NGINX_FILE -t + then + Println "$error 请检查配置错误\n" + exit 1 + fi if systemctl restart $nginx_name then Println "$info $nginx_name 重启成功\n" @@ -21779,6 +21882,15 @@ NginxConfigDomain() fi Println "$info flv 配置添加成功\n" else + server_name=${nginx_domain_servers_name[nginx_domain_servers_index]} + + if [[ $server_name =~ , ]] + then + IFS="," read -r -a domains <<< "$server_name" + + echo + inquirer list_input "选择域名: " domains server_name + fi updated=0 NginxAddNodejs if [ "$updated" -eq 1 ] @@ -22649,7 +22761,7 @@ NginxAddLocalhost() NginxAddNodejs() { - server_ip=${server_ip:-$(GetServerIp)} + proxy_cookie_domain=${server_name:-$(GetServerIp)} directive_location_1=' {"directive":"location","args":["=","/"],"block":[ @@ -22658,7 +22770,7 @@ NginxAddNodejs() {"directive":"proxy_cache_bypass","args":["1"]}, {"directive":"proxy_no_cache","args":["1"]}, {"directive":"proxy_cookie_path","args":["/","/$samesite_none"]}, - {"directive":"proxy_cookie_domain","args":["localhost","'"$server_ip"'"]} + {"directive":"proxy_cookie_domain","args":["localhost","'"$proxy_cookie_domain"'"]} ]}' directive_location_2=' @@ -22681,7 +22793,7 @@ NginxAddNodejs() {"directive":"proxy_cache_bypass","args":["1"]}, {"directive":"proxy_no_cache","args":["1"]}, {"directive":"proxy_cookie_path","args":["/","/$samesite_none"]}, - {"directive":"proxy_cookie_domain","args":["localhost","'"$server_ip"'"]} + {"directive":"proxy_cookie_domain","args":["localhost","'"$proxy_cookie_domain"'"]} ]}' directive_location_5=' @@ -22870,9 +22982,9 @@ NginxAddSameSiteNone() NginxAddDirective 2 directive_default='{"directive":"default","args":["; Secure"]}' - directive_chrome='{"directive":"~Chrom[^ \\/]+\\/8[\\d][\\.\\d]*","args":["; Secure; SameSite=None"]}' + directive_chrome='{"directive":"~Chrom[^ \\/]+\\/[89][\\d][\\.\\d]*","args":["; Secure; SameSite=None"]}' - directives=( default '~Chrom[^ \\/]+\\/8[\\d][\\.\\d]*' ) + directives=( default '~Chrom[^ \\/]+\\/[89][\\d][\\.\\d]*' ) directives_val=( default chrome ) check_directives=() check_args=( '["; Secure"]' ) @@ -23632,7 +23744,7 @@ NginxConfigDirective() NginxConfigLocalhost() { echo - config_localhost_options=( '修改指令' '添加 flv 设置' '添加 nodejs 设置' '添加 SNI 域名分流' '添加 SSL 协议分流' '添加 ALPN 协议分流' '添加 分流后端' '删除 SNI 域名分流' '删除 SSL 协议分流' '删除 ALPN 协议分流' '删除 分流后端' ) + config_localhost_options=( '修改指令' '添加 flv 设置' '添加 nodejs 设置' '添加 SNI 域名分流' '添加 SSL 协议分流' '添加 ALPN 协议分流' '添加 分流后端' '删除 SNI 域名分流' '删除 SSL 协议分流' '删除 ALPN 协议分流' '删除 分流后端' '取消' ) inquirer list_input_index "选择操作" config_localhost_options config_localhost_options_index if [ "$config_localhost_options_index" -eq 0 ] @@ -23666,6 +23778,9 @@ NginxConfigLocalhost() NginxBuildConf parse_out fi Println "$info nodejs 配置添加成功\n" + elif [ "$config_localhost_options_index" -eq 11 ] + then + Println "$i18n_canceled...\n" else NginxCheckLocalhost NginxGetStream @@ -23765,6 +23880,7 @@ NginxConfigLocalhost() Println "ALPN 协议分流:\n\n${nginx_stream_alpn_protocols_list:-无}\n\n" inquirer text_input "输入指令(分流 ALPN 协议)" alpn_protocols_directive "$i18n_cancel" ExitOnCancel alpn_protocols_directive + alpn_protocols_directive=${alpn_protocols_directive//\\/\\\\} echo inquirer text_input "输入指令值(分流后端名称)" alpn_protocols_args "$i18n_cancel" ExitOnCancel alpn_protocols_args @@ -24254,7 +24370,7 @@ NginxLogRotate() compress delaycompress notifempty - create 660 nginx root + create 660 '"$nginx_name"' root sharedscripts postrotate [ ! -f '"$nginx_prefix"'/logs/nginx.pid ] || /bin/kill -USR1 `cat '"$nginx_prefix"'/logs/nginx.pid` @@ -24265,7 +24381,7 @@ NginxLogRotate() Println "$error 日志切割定时任务设置成功 !\n" fi else - LOGROTATE_FILE=$(command -v logrotate) + LOGROTATE_FILE=$(command -v logrotate) || LOGROTATE_FILE="" if [ ! -x "$LOGROTATE_FILE" ] then @@ -24284,16 +24400,16 @@ NginxLogRotate() compress delaycompress notifempty - create 660 nginx root + create 660 '"$nginx_name"' root sharedscripts postrotate [ ! -f '"$nginx_prefix"'/logs/nginx.pid ] || /bin/kill -USR1 `cat '"$nginx_prefix"'/logs/nginx.pid` endscript } ' - fi + fi - logrotate="$logrotate + logrotate="$logrotate $IPTV_ROOT/*.log { monthly missingok @@ -24757,26 +24873,40 @@ NodejsInstall() echo -n "...100%" && Println "$info nodejs 安装完成" } -NodejsInstallMongodb() +ResourceLimit() { - Println "$info 安装 mongodb, 请等待(国内可能无法安装)..." + ReleaseCheck + + if [ ! -e /proc/sys/fs/file-max ] + then + echo 65536 > /proc/sys/fs/file-max + echo "fs.file-max=65536" >> /etc/sysctl.conf + fi + + file_max=$(< /proc/sys/fs/file-max) + + if [ "$file_max" -lt 65000 ] + then + file_max=$((file_max*95/100)) + else + file_max=64000 + fi + limits=( - "root soft nofile 65535" - "root hard nofile 65535" - "root soft nproc 65535" - "root hard nproc 65535" - "* soft nofile 64000" - "* hard nofile 64000" - "mongod soft fsize unlimited" - "mongod hard fsize unlimited" - "mongod soft cpu unlimited" - "mongod hard cpu unlimited" - "mongod soft as unlimited" - "mongod hard as unlimited" - "mongod soft memlock unlimited" - "mongod hard memlock unlimited" - "mongod soft nproc 64000" - "mongod hard nproc 64000" + "$USER soft fsize unlimited" + "$USER hard fsize unlimited" + "$USER soft cpu unlimited" + "$USER hard cpu unlimited" + "$USER soft as unlimited" + "$USER hard as unlimited" + "$USER soft memlock unlimited" + "$USER hard memlock unlimited" + "$USER soft nofile $file_max" + "$USER hard nofile $file_max" + "$USER soft nproc 64000" + "$USER hard nproc 64000" + "* soft nofile $file_max" + "* hard nofile $file_max" ) limits_append="" @@ -24790,23 +24920,77 @@ NodejsInstallMongodb() if [ -n "$limits_append" ] then + # systemd ignores limits set in the /etc/security/limits.conf echo -e "$limits_append" >> "/etc/security/limits.conf" fi ulimit -f unlimited ulimit -t unlimited ulimit -v unlimited - ulimit -n 64000 + ulimit -l unlimited + ulimit -n $file_max ulimit -m unlimited - ulimit -u 32000 + ulimit -u 64000 + + if [ "$release" == "rpm" ] + then + if [ ! -e ~/.bash_profile ] || ! grep -q ulimit < ~/.bash_profile + then +cat >> ~/.bash_profile << EOF +ulimit -f unlimited +ulimit -t unlimited +ulimit -v unlimited +ulimit -l unlimited +ulimit -n $file_max +ulimit -m unlimited +ulimit -u 64000 +EOF + fi + else + if [ ! -e ~/.profile ] || ! grep -q ulimit < ~/.profile + then +cat >> ~/.profile << EOF +ulimit -f unlimited +ulimit -t unlimited +ulimit -v unlimited +ulimit -l unlimited +ulimit -n $file_max +ulimit -m unlimited +ulimit -u 64000 +EOF + fi + fi + + # The limits defined in these files are set by PAM when starting a login session, but daemons started by systemd do not use PAM login sessions + #if [ ! -e /etc/security/limits.d/99-mongodb-nproc.conf ] && ls -A /etc/security/limits.d/*-nproc.conf > /dev/null 2>&1 + #then + # echo -e "mongodb soft nproc 64000\nmongodb hard nproc 64000" > /etc/security/limits.d/99-mongodb-nproc.conf + #fi +} + +NodejsInstallMongodb() +{ + Println "$info 安装 mongodb, 请等待(国内可能无法安装)..." + + ResourceLimit - ReleaseCheck if [ "$release" == "rpm" ] then + ArchCheck + if [ "$arch" == "arm64" ] + then + arch_path="aarch64" + elif [ "$arch" == "x86_64" ] || [ "$arch" == "s390x" ] + then + arch_path="$arch" + else + Println "$error 不支持当前系统\n" + exit 1 + fi printf '%s' " [mongodb-org-4.4] name=MongoDB Repository -baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.4/x86_64/ +baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.4/$arch_path/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc @@ -24823,19 +25007,19 @@ gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc then if grep -q "xenial" < "/etc/apt/sources.list" then - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb [ arch=amd64,arm64,s390x ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list elif grep -q "bionic" < "/etc/apt/sources.list" then - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb [ arch=amd64,arm64,s390x ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list else - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb [ arch=amd64,arm64,s390x ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list fi else if grep -q "stretch" < "/etc/apt/sources.list" then - echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list else - echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list + echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list fi fi @@ -24845,16 +25029,16 @@ gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc if [[ $(ps --no-headers -o comm 1) == "systemd" ]] then - if ! systemctl start mongod > /dev/null 2>&1 - then - systemctl daemon-reload - systemctl start mongod > /dev/null 2>&1 - fi + sed -i "s/LimitNOFILE=.*/LimitNOFILE=$file_max/" /lib/systemd/system/mongod.service + systemctl daemon-reload + systemctl start mongod systemctl enable mongod else service mongod start fi + sleep 3 + Println "$info mongodb 安装成功" } @@ -24885,6 +25069,16 @@ NodejsConfig() then NginxListDomain NginxSelectDomainServer + + server_name=${nginx_domain_servers_name[nginx_domain_servers_index]} + + if [[ $server_name =~ , ]] + then + IFS="," read -r -a domains <<< "$server_name" + + echo + inquirer list_input "选择域名: " domains server_name + fi else NginxListLocalhost NginxSelectLocalhostServer @@ -25069,7 +25263,7 @@ V2rayInstall() if [ "$v2ray_name" == "v2ray" ] then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25077,7 +25271,7 @@ V2rayInstall() | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25122,7 +25316,7 @@ V2rayUpdate() if [ "$v2ray_name" == "v2ray" ] then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25130,7 +25324,7 @@ V2rayUpdate() | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_BACKUP"; } \ + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ | sed "s+nobody+$v2ray_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -25263,7 +25457,7 @@ V2rayConfigUpdate() V2rayStatus() { - systemctl status $v2ray_name --no-pager + systemctl --no-pager status $v2ray_name } V2raySetListen() @@ -26477,7 +26671,7 @@ V2rayAddInbound() V2raySetSniffingDomainsExcluded fi - if [ "$self" == "ibm" ] || [ "$self" == "ibm.sh" ] + if [ "$self" == "ibm" ] then V2raySetSecurity V2raySetTag @@ -27808,10 +28002,7 @@ V2rayListInboundAccountLink() Println "$info 安装 ImageMagick" ImageMagickInstall fi - if [[ ! -x $(command -v qrencode) ]] - then - DepInstall qrencode - fi + DepInstall qrencode qrencode -s 1 -o "$HOME/vmess_link.png" "vmess://$vmess_link" /usr/local/bin/imgcat --half-height "$HOME/vmess_link.png" fi @@ -30857,7 +31048,7 @@ TrojanInstall() Println "$info 安装 $trojan_name..." - { curl -s -m 10 "$TR_LINK" || curl -s -m 30 "$TR_LINK_BACKUP"; } \ + { curl -s -m 10 "$TR_LINK" || curl -s -m 30 "$TR_LINK_FALLBACK"; } \ | sed "s+nobody+$trojan_name+g" \ | sed "s+ 'sha1'++g" \ | sed "s+ 'sha256'++g" \ @@ -32993,7 +33184,7 @@ CloudflareSetWorkerUpstream() then Println "$tip 比如: youdomain.com/path" inquirer text_input "输入 worker: $cf_worker_name 源站地址: " cf_worker_upstream "$i18n_cancel" - ExitOnCancel + ExitOnCancel cf_worker_upstream fi } @@ -33021,7 +33212,7 @@ CloudflareAddWorker() then wrangler generate "stream_proxy" wget --timeout=10 --tries=1 --no-check-certificate "$STREAM_PROXY_LINK" -qO "$CF_WORKERS_ROOT/stream_proxy/index.js" \ - || wget --timeout=10 --tries=3 --no-check-certificate "$STREAM_PROXY_LINK_BACKUP" -qO "$CF_WORKERS_ROOT/stream_proxy/index.js" + || wget --timeout=10 --tries=3 --no-check-certificate "$STREAM_PROXY_LINK_FALLBACK" -qO "$CF_WORKERS_ROOT/stream_proxy/index.js" fi CloudflareSetWorkerName @@ -33035,7 +33226,7 @@ CloudflareAddWorker() then wrangler generate "xtream_codes_proxy" wget --timeout=10 --tries=1 --no-check-certificate "$XTREAM_CODES_PROXY_LINK" -qO "$CF_WORKERS_ROOT/xtream_codes_proxy/index.js" \ - || wget --timeout=10 --tries=3 --no-check-certificate "$XTREAM_CODES_PROXY_LINK_BACKUP" -qO "$CF_WORKERS_ROOT/xtream_codes_proxy/index.js" + || wget --timeout=10 --tries=3 --no-check-certificate "$XTREAM_CODES_PROXY_LINK_FALLBACK" -qO "$CF_WORKERS_ROOT/xtream_codes_proxy/index.js" fi CloudflareSetWorkerName @@ -33337,7 +33528,7 @@ CloudflareDeployWorker() do [ -z "$cf_workers_num" ] && Println "$i18n_canceled...\n" && exit 1 - if [[ $cf_workers_num -eq $((cf_workers_count+1)) ]] + if [ "$cf_workers_num" == "$((cf_workers_count+1))" ] then for((i=0;i 切换/更新 语言\"` " exit @@ -39373,9 +39569,16 @@ then UpdateSelf fi -self=${0##*/} +if [[ -x $(command -v readlink) ]] && [ -L "$0" ] && alternative=$(readlink "$0") && [ -L "$alternative" ] +then + self=${alternative##*/} +else + self=${0##*/} +fi -if [ "$self" == "ibm" ] || [ "$self" == "ibm.sh" ] +self=${self%.*} + +if [ "$self" == "ibm" ] then ShFileCheck @@ -39431,7 +39634,7 @@ then IbmCfMenu fi exit 0 -elif [ "$self" == "cf" ] || [ "$self" == "cf.sh" ] +elif [ "$self" == "cf" ] then ShFileCheck @@ -39483,7 +39686,7 @@ then CloudflarePartnerMenu fi exit 0 -elif [ "$self" == "or" ] || [ "$self" == "or.sh" ] +elif [ "$self" == "or" ] then ShFileCheck @@ -39496,6 +39699,7 @@ then if [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then + ResourceLimit echo "[Unit] Description=$nginx_name After=syslog.target network-online.target remote-fs.target nss-lookup.target @@ -39510,10 +39714,21 @@ ExecStartPost=/bin/sleep 0.1 ExecReload=$nginx_prefix/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT \$MAINPID PrivateTmp=true +# file size +LimitFSIZE=infinity +# cpu time +LimitCPU=infinity +# virtual memory size +LimitAS=infinity +# open files +LimitNOFILE=$file_max +# processes/threads +LimitNPROC=64000 +# locked memory +LimitMEMLOCK=infinity [Install] -WantedBy=multi-user.target -" > /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" @@ -39537,11 +39752,10 @@ WantedBy=multi-user.target ${green}11.${normal} 开关 ${green}12.${normal} 重启 ———————————— - ${green}13.${normal} 删除域名 - ${green}14.${normal} 日志切割 -———————————— - ${green}15.${normal} 安装 nodejs - ${green}16.${normal} 识别 cloudflare/ibm ip + ${green}13.${normal} 配置 日志切割 + ${green}14.${normal} 配置 nodejs + ${green}15.${normal} 识别 cloudflare/ibm ip + ${green}16.${normal} 删除域名 $tip 输入: or 打开面板 @@ -39594,12 +39808,9 @@ WantedBy=multi-user.target NginxRestart ;; 13) - NginxDeleteDomain - ;; - 14) NginxLogRotate ;; - 15) + 14) [ ! -d "$IPTV_ROOT" ] && Println "$error 请先输入 tv 安装 !\n" && exit 1 if [[ ! -x $(command -v node) ]] || [[ ! -x $(command -v npm) ]] then @@ -39617,14 +39828,17 @@ WantedBy=multi-user.target Println "$error nodejs 配置已存在\n" && exit 1 fi ;; - 16) + 15) NginxUpdateCFIBMip ;; + 16) + NginxDeleteDomain + ;; *) Println "$error $i18n_input_correct_number [1-16]\n" ;; esac exit 0 -elif [ "$self" == "nx" ] || [ "$self" == "nx.sh" ] +elif [ "$self" == "nx" ] then ShFileCheck @@ -39637,6 +39851,7 @@ then if [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then + ResourceLimit echo "[Unit] Description=$nginx_name After=syslog.target network-online.target remote-fs.target nss-lookup.target @@ -39651,10 +39866,21 @@ ExecStartPost=/bin/sleep 0.1 ExecReload=$nginx_prefix/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT \$MAINPID PrivateTmp=true +# file size +LimitFSIZE=infinity +# cpu time +LimitCPU=infinity +# virtual memory size +LimitAS=infinity +# open files +LimitNOFILE=$file_max +# processes/threads +LimitNPROC=64000 +# locked memory +LimitMEMLOCK=infinity [Install] -WantedBy=multi-user.target -" > /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" @@ -39678,16 +39904,16 @@ WantedBy=multi-user.target ${green}11.${normal} 开关 ${green}12.${normal} 重启 ———————————— - ${green}13.${normal} 删除域名 - ${green}14.${normal} 日志切割 + ${green}13.${normal} 配置 日志切割 + ${green}14.${normal} 配置 nodejs + ${green}15.${normal} 配置 postfix + ${green}16.${normal} 配置 mmproxy + ${green}17.${normal} 配置 dnscrypt proxy + ${green}18.${normal} 识别 cloudflare/ibm ip + ${green}19.${normal} 删除域名 ———————————— - ${green}15.${normal} 安装 nodejs - ${green}16.${normal} 安装 pdf2htmlEX - ${green}17.${normal} 安装 tesseract - ${green}18.${normal} 配置 postfix - ${green}19.${normal} 配置 mmproxy - ${green}20.${normal} 配置 dnscrypt proxy - ${green}21.${normal} 识别 cloudflare/ibm ip + ${green}20.${normal} 安装 pdf2htmlEX + ${green}21.${normal} 安装 tesseract $tip 输入: nx 打开面板 @@ -39740,12 +39966,9 @@ WantedBy=multi-user.target NginxRestart ;; 13) - NginxDeleteDomain - ;; - 14) NginxLogRotate ;; - 15) + 14) [ ! -d "$IPTV_ROOT" ] && Println "$error 请先输入 tv 安装 !\n" && exit 1 if [[ ! -x $(command -v node) ]] || [[ ! -x $(command -v npm) ]] then @@ -39763,38 +39986,7 @@ WantedBy=multi-user.target Println "$error nodejs 配置已存在\n" && exit 1 fi ;; - 16) - if [[ ! -x $(command -v pdf2htmlEX) ]] - then - echo - AskIfContinue n "`gettext \"因为是编译 pdf2htmlEX, 耗时会很长, 是否继续\"`" - Pdf2htmlInstall - Println "$info pdf2htmlEX 安装完成, 输入 source /etc/profile 可立即使用\n" - else - Println "$error pdf2htmlEX 已存在!\n" - fi - ;; - 17) - if [[ ! -x $(command -v tesseract) ]] - then - DepsCheck - echo - if [ "$release" == "ubu" ] - then - add-apt-repository ppa:alex-p/tesseract-ocr -y - AptUpdate - apt-get -y install tesseract - elif [ "$release" == "deb" ] - then - Println "$info 参考 https://notesalexp.org/tesseract-ocr/ ...\n" - else - Println "$info 参考 https://tesseract-ocr.github.io/tessdoc/Home.html ...\n" - fi - else - Println "$error tesseract 已存在!\n" - fi - ;; - 18) + 15) if [[ ! -x $(command -v postfix) ]] then ReleaseCheck @@ -39856,25 +40048,30 @@ WantedBy=multi-user.target fi Println "$info smtp 设置成功\n" ;; - 19) - if [ ! -d ~/mmproxy ] + 16) + if [ ! -e ~/allowed-subnets.txt ] then - if [[ ! -x $(command -v git) ]] + echo -en "0.0.0.0/0\n::/0\n" > ~/allowed-subnets.txt + fi + + if [[ ! -x "$HOME/go/bin/go-mmproxy" ]] + then + Println "$info 安装 go-mmproxy" + + GoInstall + go get github.com/path-network/go-mmproxy + + if [[ ! -x $(command -v go-mmproxy) ]] then - Spinner "安装 git" GitInstall + export PATH="$PATH:$HOME/go/bin" + ReleaseCheck + if [ "$release" == "rpm" ] + then + echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.bash_profile + else + echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.profile + fi fi - trap ' - rm -rf ~/mmproxy - ' EXIT - cd ~ - git clone https://github.com/cloudflare/mmproxy - cd mmproxy - git clone https://github.com/sustrik/libmill.git - git clone https://github.com/seccomp/libseccomp.git - - make CC=clang - echo -en "0.0.0.0/0\n::/0\n" > allowed-networks.txt - trap - EXIT fi echo @@ -39884,9 +40081,11 @@ WantedBy=multi-user.target if [ "$mmproxy_opotions_index" -eq 0 ] then mmproxy_name="acme" - elif [ "$mmproxy_opotions_index" -eq 0 ] + acme_tip="(acme 监听端口)" + elif [ "$mmproxy_opotions_index" -eq 1 ] then mmproxy_name="ssh" + ssh_tip="(ssh 监听端口)" else echo inquirer text_input "输入 mmproxy 配置名称(英文)" mmproxy_name "$i18n_cancel" @@ -39903,21 +40102,29 @@ WantedBy=multi-user.target fi fi - echo - inquirer text_input "输入 mmproxy 监听端口: " mmproxy_listen_port "随机" + Println "$tip 比如 nginx 分流后端: 127.0.0.1:1234" + inquirer text_input "输入 mmproxy 监听 地址+端口: " mmproxy_listen "随机" - if [ "$mmproxy_listen_port" == "随机" ] + if [ "$mmproxy_listen" == "随机" ] then - mmproxy_listen_port=$(GetFreePort) + mmproxy_listen="127.0.0.1:$(GetFreePort)" fi - echo - inquirer text_input "输入前端(比如 nginx) 分流 ipv4 端口: " mmproxy_target_v4_port "$i18n_cancel" - ExitOnCancel mmproxy_target_v4_port + if [ "$mmproxy_name" == "ssh" ] + then + Println "$tip 请确保已经设置 ssh 监听地址和端口" + fi - echo - inquirer text_input "输入前端(比如 nginx) 分流 ipv6 端口: " mmproxy_target_v6_port "$i18n_cancel" - ExitOnCancel mmproxy_target_v6_port + Println "$tip 比如: 127.0.0.1:2222" + inquirer text_input "输入 ipv4 分流目标 地址+端口${acme_tip:-}${ssh_tip:-}: " mmproxy_target_v4 "$i18n_cancel" + ExitOnCancel mmproxy_target_v4 + + inquirer text_input "输入 ipv6 分流目标 地址+端口${acme_tip:-}${ssh_tip:-}: " mmproxy_target_v6 "[::1]:${mmproxy_target_v4#*:}" + + if [ -e "/etc/systemd/system/mmproxy-$mmproxy_name.service" ] + then + reload=1 + fi echo "[Unit] Description=mmproxy-$mmproxy_name @@ -39925,30 +40132,28 @@ After=syslog.target network-online.target nss-lookup.target Wants=network-online.target [Service] -ExecStart=$HOME/mmproxy/mmproxy --allowed-networks $HOME/mmproxy/allowed-networks.txt -l 127.0.0.1:$mmproxy_listen_port -4 127.0.0.1:$mmproxy_target_v4_port -6 [::1]:$mmproxy_target_v6_port +ExecStart=$HOME/go/bin/go-mmproxy --allowed-subnets $HOME/allowed-subnets.txt -l $mmproxy_listen -4 $mmproxy_target_v4 -6 $mmproxy_target_v6 Restart=on-failure [Install] WantedBy=multi-user.target" > "/etc/systemd/system/mmproxy-$mmproxy_name.service" - if ! grep -q 'iif lo lookup 100' < <(ip rule list) + if [ "${reload:-0}" -eq 1 ] then - ip -4 rule add from 127.0.0.1/8 iif lo table 100 - ip -6 rule add from ::1/128 iif lo table 100 - - ip route add local 0.0.0.0/0 dev lo table 100 - ip -6 route add local ::/0 dev lo table 100 + systemctl daemon-reload + systemctl enable "mmproxy-$mmproxy_name" + systemctl restart "mmproxy-$mmproxy_name" + else + systemctl enable "mmproxy-$mmproxy_name" + systemctl start "mmproxy-$mmproxy_name" fi - systemctl enable "mmproxy-$mmproxy_name" - systemctl start "mmproxy-$mmproxy_name" - if [ ! -f ~/ip.sh ] then echo "#!/bin/bash -ip -4 rule add from 127.0.0.1/8 iif lo table 100 -ip -6 rule add from ::1/128 iif lo table 100 +ip rule add from 127.0.0.1/8 iif lo table 100 ip route add local 0.0.0.0/0 dev lo table 100 +ip -6 rule add from ::1/128 iif lo table 100 ip -6 route add local ::/0 dev lo table 100" > ~/ip.sh chmod +x ~/ip.sh fi @@ -39966,13 +40171,16 @@ $HOME/ip.sh" > /etc/rc.local if [[ $(systemctl is-active rc-local) == "inactive" ]] then - systemctl enbale rc-local - systemctl start rc-local + systemctl enable rc-local || true + if ! grep -q 'iif lo lookup 100' < <(ip rule list) + then + systemctl start rc-local || true + fi fi Println "$info mmproxy-$mmproxy_name 设置成功\n" ;; - 20) + 17) DepInstall curl DNSCRYPT_ROOT=$(dirname ~/dnscrypt-*/dnscrypt-proxy | sort | tail -1) @@ -40030,7 +40238,12 @@ $HOME/ip.sh" > /etc/rc.local exit 0 fi - arch=$(uname -m) + ArchCheck + + if [ "$arch" != "arm64" ] && grep -q "arm" <<< "$arch" + then + arch="arm" + fi if dnscrypt_version=$(curl -s -Lm 20 "$FFMPEG_MIRROR_LINK/dnscrypt.json" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') then @@ -40137,14 +40350,48 @@ $HOME/ip.sh" > /etc/rc.local Println "$error 无法连接服务器, 请稍后再试\n" fi ;; - 21) + 18) NginxUpdateCFIBMip ;; + 19) + NginxDeleteDomain + ;; + 20) + if [[ ! -x $(command -v pdf2htmlEX) ]] + then + echo + AskIfContinue n "`gettext \"因为是编译 pdf2htmlEX, 耗时会很长, 是否继续\"`" + Pdf2htmlInstall + Println "$info pdf2htmlEX 安装完成, 输入 source /etc/profile 可立即使用\n" + else + Println "$error pdf2htmlEX 已存在!\n" + fi + ;; + 21) + if [[ ! -x $(command -v tesseract) ]] + then + DepsCheck + echo + if [ "$release" == "ubu" ] + then + add-apt-repository ppa:alex-p/tesseract-ocr -y + AptUpdate + apt-get -y install tesseract + elif [ "$release" == "deb" ] + then + Println "$info 参考 https://notesalexp.org/tesseract-ocr/ ...\n" + else + Println "$info 参考 https://tesseract-ocr.github.io/tessdoc/Home.html ...\n" + fi + else + Println "$error tesseract 已存在!\n" + fi + ;; *) Println "$error $i18n_input_correct_number [1-21]\n" ;; esac exit 0 -elif [ "$self" == "v2" ] || [ "$self" == "v2.sh" ] || [ "$self" == "V2.sh" ] || [ "$self" == "x" ] || [ "$self" == "x.sh" ] || [ "$self" == "xray.sh" ] +elif [ "$self" == "v2" ] || [ "$self" == "V2" ] || [ "$self" == "x" ] || [ "$self" == "xray" ] then ShFileCheck [ ! -d "$IPTV_ROOT" ] && JQ_FILE="/usr/local/bin/jq" @@ -40152,19 +40399,19 @@ then v2ray_name="v2ray" tls_name="TLS" - if [ "$self" == "x" ] || [ "$self" == "x.sh" ] || [ "$self" == "xray.sh" ] + if [ "$self" == "x" ] || [ "$self" == "xray" ] then v2ray_sh="x" v2ray_name="xray" tls_name="XTLS" V2_FILE="/usr/local/bin/x" V2_LINK="https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh" - V2_LINK_BACKUP="$FFMPEG_MIRROR_LINK/xray_install-release.sh" + V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xray_install-release.sh" V2CTL_FILE="/usr/local/bin/xray" V2_CONFIG="/usr/local/etc/xray/config.json" elif [ -d "/etc/v2ray/" ] then - systemctl disable v2ray.service --now > /dev/null 2> /dev/null || true + systemctl disable v2ray --now > /dev/null 2> /dev/null || true rm -rf /usr/bin/v2ray/ rm -f /etc/systemd/system/v2ray.service rm -f /lib/systemd/system/v2ray.service @@ -40192,7 +40439,7 @@ then case $* in "e") [ ! -e "$V2_CONFIG" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 - vim "$V2_CONFIG" && exit 0 + editor "$V2_CONFIG" && exit 0 ;; *) ;; @@ -40383,7 +40630,7 @@ then ;; esac exit 0 -elif [ "$self" == "cx" ] || [ "$self" == "cx.sh" ] +elif [ "$self" == "cx" ] then [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 @@ -40519,7 +40766,7 @@ ${green}8.${normal} 浏览频道 ;; esac exit 0 -elif [ "$self" == "arm" ] || [ "$self" == "arm.sh" ] +elif [ "$self" == "arm" ] then if [[ ! -x $(command -v armbian-config) ]] then @@ -40799,7 +41046,7 @@ method=ignore" > /etc/NetworkManager/system-connections/armbian.nmconnection exit 1 fi - if [[ $(systemctl is-active docker.service) == "inactive" ]] + if [[ $(systemctl is-active docker) == "inactive" ]] then systemctl start docker fi @@ -41453,7 +41700,7 @@ config interface 'lan' ;; esac exit 0 -elif [ "$self" == "pve" ] || [ "$self" == "pve.sh" ] +elif [ "$self" == "pve" ] then if [[ ! -x $(command -v pveum) ]] then @@ -41470,9 +41717,9 @@ then ${green}1.${normal} 设置 apt 源 ${green}2.${normal} 设置 vimrc ${green}3.${normal} 设置 显示器 -———————————— ${green}4.${normal} 查看 温度 / 风扇 ${green}5.${normal} 设置 风扇 +———————————— ${green}6.${normal} 安装 升级 dnscrypt ${green}7.${normal} 安装 qemu-guest-agent ${green}8.${normal} 安装 openwrt-v2ray @@ -41607,15 +41854,15 @@ then fi echo - nbfc_options=( '查看状态' '风扇切换为手动控制' '设置风扇转速' '搜索配置' '应用配置' ) - inquirer list_input "选择操作" nbfc_options nbfc_option + nbfc_options=( '查看状态' '切换风扇手动/自动控制' '设置风扇转速' '搜索配置' '应用配置' ) + inquirer list_input_index "选择操作" nbfc_options nbfc_options_index cd /opt/nbfc - if [ "$nbfc_option" == "查看状态" ] + if [ "$nbfc_options_index" -eq 0 ] then mono nbfc.exe status --all - elif [ "$nbfc_option" == "风扇切换为手动控制" ] + elif [ "$nbfc_options_index" -eq 1 ] then echo inquirer text_input "输入寄存器地址, 比如 0x93: " register_address "$i18n_cancel" @@ -41634,7 +41881,7 @@ then fi Println "$tip 不一定写入成功, 请自行检查\n" - elif [ "$nbfc_option" == "设置风扇转速" ] + elif [ "$nbfc_options_index" -eq 2 ] then Println "$tip 请确保风扇处于手动控制状态" echo @@ -41667,10 +41914,10 @@ then Println "$tip 操作成功\n" fi - elif [ "$nbfc_option" == "搜索配置" ] + elif [ "$nbfc_options_index" -eq 3 ] then mono nbfc.exe config -r - elif [ "$nbfc_option" == "应用配置" ] + elif [ "$nbfc_options_index" -eq 4 ] then echo inquirer text_input "输入配置名称, 比如: Acer Aspire 5745G" config_name "$i18n_cancel" @@ -42613,13 +42860,17 @@ then ;; "e") [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 - vim "$CHANNELS_FILE" && exit 0 + editor "$CHANNELS_FILE" && exit 0 ;; "ee") [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 GetDefault [ -z "$d_sync_file" ] && Println "$error sync_file 未设置, 请检查 !\n" && exit 1 - vim "${d_sync_file%% *}" && exit 0 + echo + edit_options=($d_sync_file) + inquirer list_input "选择修改的文件" edit_options edit_option + editor "$edit_option" + exit 0 ;; "d") [ ! -d "$IPTV_ROOT" ] && Println "$error 尚未安装, 请检查 !\n" && exit 1 @@ -42758,7 +43009,7 @@ then #Println "输入镜像网站链接(比如: $FFMPEG_MIRROR_LINK)" #read -p "$i18n_default_cancel" FFMPEG_LINK - #[ -z "$FFMPEG_LINK" ] && echo "$i18n_canceled...\n" && exit 1 + #[ -z "$FFMPEG_LINK" ] && Println "$i18n_canceled...\n" && exit 1 #sed -i "s+https://johnvansickle.com/ffmpeg/\(builds\|releases\)/\(.*\).tar.xz\"+$FFMPEG_LINK/\1/\2.tar.xz\"+g" "$FFMPEG_MIRROR_ROOT/index.html" sed -i "s+https://johnvansickle.com/ffmpeg/\(builds\|releases\)/\(.*\).tar.xz\"+\1/\2.tar.xz\"+g" "$FFMPEG_MIRROR_ROOT/index.html" @@ -42820,48 +43071,48 @@ then Println "$error jq 下载出错, 无法连接 github ?" fi + archs=( 32 64 arm32-v5 arm32-v6 arm32-v7a arm64-v8a s390x) + if v2ray_ver=$(curl -s -m 30 "https://api.github.com/repos/v2fly/v2ray-core/releases/latest" | $JQ_FILE -r '.tag_name') then - if [ ! -e "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip" ] || [ ! -e "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip" ] - then - Println "$info 下载 v2ray $v2ray_ver ..." - mkdir -p "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/" - if curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-64.zip" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip_tmp" \ - && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-32.zip" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip_tmp" \ - && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-64.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip.dgst_tmp" \ - && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-32.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip.dgst_tmp" + mkdir -p "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/" + for arch in "${archs[@]}" + do + if [ ! -e "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip" ] then - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip" - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip" - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-64.zip.dgst" - mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-32.zip.dgst" - else - Println "$error v2ray $v2ray_ver 下载出错, 无法连接 github ?" + Println "$info 下载 v2ray-linux-$arch $v2ray_ver ..." + if curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-$arch.zip" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip_tmp" \ + && curl -s -L "https://github.com/v2fly/v2ray-core/releases/download/$v2ray_ver/v2ray-linux-$arch.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip.dgst_tmp" + then + mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip" + mv "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/v2ray/$v2ray_ver/v2ray-linux-$arch.zip.dgst" + else + Println "$error v2ray-linux-$arch $v2ray_ver 下载出错, 无法连接 github ?" + fi fi - fi + done else Println "$error v2ray $v2ray_ver 下载出错, 无法连接 github ?" fi if xray_ver=$(curl -s -m 30 "https://api.github.com/repos/XTLS/Xray-core/releases/latest" | $JQ_FILE -r '.tag_name') then - if [ ! -e "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip" ] || [ ! -e "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip" ] - then - Println "$info 下载 xray $xray_ver ..." - mkdir -p "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/" - if curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-64.zip" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip_tmp" \ - && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-32.zip" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip_tmp" \ - && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-64.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip.dgst_tmp" \ - && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-32.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip.dgst_tmp" + mkdir -p "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/" + for arch in "${archs[@]}" + do + if [ ! -e "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip" ] then - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip" - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip" - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-64.zip.dgst" - mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-32.zip.dgst" - else - Println "$error xray $xray_ver 下载出错, 无法连接 github ?" + Println "$info 下载 Xray-linux-$arch $xray_ver ..." + if curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-$arch.zip" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip_tmp" \ + && curl -s -L "https://github.com/XTLS/Xray-core/releases/download/$xray_ver/Xray-linux-$arch.zip.dgst" -o "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip.dgst_tmp" + then + mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip" + mv "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip.dgst_tmp" "$FFMPEG_MIRROR_ROOT/xray/$xray_ver/Xray-linux-$arch.zip.dgst" + else + Println "$error Xray-linux-$arch $xray_ver 下载出错, 无法连接 github ?" + fi fi - fi + done else Println "$error xray $xray_ver 下载出错, 无法连接 github ?" fi @@ -42917,7 +43168,7 @@ then if dnscrypt_ver=$(curl -s -m 30 "https://api.github.com/repos/DNSCrypt/dnscrypt-proxy/releases/latest" | $JQ_FILE -r '.tag_name') then - archs=( arm64 x86_64 ) + archs=( arm arm64 i386 x86_64 ) for arch in "${archs[@]}" do @@ -43218,6 +43469,40 @@ then sed -i "0,/sh_debug=.*/s//sh_debug=${2:-1}/" "$SH_FILE" exit 0 ;; + "ed"|"editor") + ReleaseCheck + DepInstall vim + if [ "$release" == "rpm" ] + then + alternatives --config editor + else + update-alternatives --config editor + fi + exit 0 + ;; + "a") + if [[ ! -x $(command -v readlink) ]] + then + Println "$error 系统不支持 readlink\n" + exit 1 + fi + echo + inquirer text_input "输入自定义命令名称" name "$i18n_cancel" + ExitOnCancel name + if command -v "$name" > /dev/null + then + Println "$error 命令已经存在\n" + exit 1 + fi + echo + alternative_options=( nginx openresty xray v2ray armbian "proxmox ve" + "ibm cloud foundry" "cloudflare partner,workers" ffmpeg ) + inquirer list_input_index "选择执行的脚本" alternative_options alternative_options_index + commands=( NX_FILE OR_FILE X_FILE V2_FILE ARM_FILE PVE_FILE IBM_FILE CF_FILE SH_FILE ) + ln -s ${!commands[alternative_options_index]} /usr/bin/$name + Println "$info 自定义命令 $name 添加成功\n" + exit 0 + ;; "c") to_locale=${2:-} new_locale="" diff --git a/scripts/fengshows_proxy.js b/scripts/fengshows_proxy.js index 00c1612..4d30995 100644 --- a/scripts/fengshows_proxy.js +++ b/scripts/fengshows_proxy.js @@ -256,6 +256,7 @@ async function handleRequest(request) { response.headers.set("Access-Control-Allow-Origin", requestOrigin) } + response.headers.set("Access-Control-Allow-Credentials", true) response.headers.append("Vary", "Origin") return response diff --git a/scripts/stream_proxy.js b/scripts/stream_proxy.js index 1e75827..aa2de46 100644 --- a/scripts/stream_proxy.js +++ b/scripts/stream_proxy.js @@ -247,6 +247,7 @@ async function handleRequest(request) { response.headers.set("Access-Control-Allow-Origin", requestOrigin) } + response.headers.set("Access-Control-Allow-Credentials", true) response.headers.append("Vary", "Origin") return response diff --git a/scripts/xtream_codes_proxy.js b/scripts/xtream_codes_proxy.js index 57a072a..99166f7 100644 --- a/scripts/xtream_codes_proxy.js +++ b/scripts/xtream_codes_proxy.js @@ -420,6 +420,7 @@ async function handleRequest(request) { response.headers.set("Access-Control-Allow-Origin", requestOrigin) } + response.headers.set("Access-Control-Allow-Credentials", true) response.headers.append("Vary", "Origin") return response