#!/bin/sh [ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd) . "$CRASHDIR"/libs/web_json.sh . "$CRASHDIR"/libs/set_config.sh . "$CRASHDIR"/libs/web_get_lite.sh . "$CRASHDIR"/menus/running_status.sh . "$CRASHDIR"/configs/gateway.cfg . "$CRASHDIR"/configs/ShellCrash.cfg TMPDIR='/tmp/ShellCrash' API="https://api.telegram.org/bot$TG_TOKEN" STATE_FILE="$TMPDIR/tgbot_state" LOGFILE="$TMPDIR/tgbot.log" OFFSET=0 ### --- 基础函数 --- ### web_download(){ setproxy if curl --version >/dev/null 2>&1; then curl -kfsSl "$1" -o "$2" else wget -Y on -q --timeout=3 -O "$2" "$1" fi } web_upload(){ curl -ksSfl -X POST --connect-timeout 20 "$API/sendDocument" -F "chat_id=$TG_CHATID" -F "document=@$1" >/dev/null } send_msg(){ TEXT="$1" web_json_post "$API/sendMessage" "{\"chat_id\":\"$TG_CHATID\",\"text\":\"$TEXT\",\"parse_mode\":\"Markdown\"}" } send_help(){ TEXT=$(cat </dev/null 2>&1;then CURL_KB=$(cat < "$LOGFILE" } do_stop_fw(){ redir_mod_bf=$redir_mod firewall_area=4 setconfig firewall_area 4 "$CRASHDIR"/start.sh stop_firewall echo "ShellCrash 已切换到纯净模式!" > "$LOGFILE" } do_restart(){ "$CRASHDIR"/start.sh restart echo "ShellCrash 服务已重启!" > "$LOGFILE" } do_set_sub(){ #echo "$1" "$2" >> "$CRASHDIR"/configs/providers.cfg echo "错误,还未完成的功能!" > "$LOGFILE" } transport(){ #文件传输 case "$CALLBACK" in "ts_get_log") web_upload "$TMPDIR"/ShellCrash.log send_menu ;; "ts_get_bak") now=$(date +%Y%m%d_%H%M%S) FILE="$TMPDIR/configs_$now.tar.gz" tar -zcf "$FILE" -C "$CRASHDIR/configs/" . web_upload "$FILE" rm -rf "$FILE" send_menu ;; "ts_get_ccf") FILE="$TMPDIR/$config_type.tar.gz" tar -zcf "$FILE" -C "$CRASHDIR/${config_type}s/" . web_upload "$FILE" rm -rf "$FILE" send_menu ;; "ts_up_core") FILE_TYPE=1 send_msg "请发送需要上传的内核,必须是以tar.gz,.gz或.upx结尾的【${corename}】内核!" ;; "ts_up_bak") FILE_TYPE=2 send_msg "请发送需要还原的备份文件,必须是【.tar.gz】格式!" ;; "ts_up_ccf") FILE_TYPE=3 send_msg "请发送需要上传的配置文件,必须是【.${config_type}】格式,支持自定义配置文件" ;; esac } ### --- 轮询主进程 --- ### polling(){ while true; do UPDATES=$(web_get_lite "$API/getUpdates?timeout=25&offset=$OFFSET") echo "$UPDATES" | grep -q '"update_id"' || { sleep 10 #防止网络不佳时疯狂请求 continue } OFFSET=$(echo "$UPDATES" | grep -o '"update_id":[0-9]*' | tail -n1 | cut -d: -f2) OFFSET=$((OFFSET + 1)) ### --- 校验ChatID --- ### CHATID=$(echo "$UPDATES" | grep -o '"id":[0-9]*' | tail -n1 | cut -d: -f2) [ "$CHATID" != "$TG_CHATID" ] && continue ### --- 处理按钮事件 --- ### CALLBACK=$(echo "$UPDATES" | grep -o '"data":"[^"]*"' | head -n1 | sed 's/.*:"//;s/"$//') FILE_ID=$(echo "$UPDATES" | sed 's/"callback_query".*//g' | grep -o '"file_id":"[^"]*"' | head -n1 | sed 's/.*:"//;s/"$//') [ -n "$FILE_ID" ] && { download_file continue } [ -n "$CALLBACK" ] && case "$CALLBACK" in "start_redir") if [ "$firewall_area" = 4 ];then do_start_fw send_msg "已切换到$redir_mod_bf!" else send_msg "当前已经是$redir_mod!" fi send_menu continue ;; "stop_redir") if [ "$firewall_area" != 4 ];then do_stop_fw send_msg "已切换到纯净模式" else send_msg "当前已经是纯净模式!" fi send_menu continue ;; "restart") do_restart send_msg "🔄 服务已重启" sleep 10 send_menu continue ;; "readlog") send_msg "📄 日志内容如下(已过滤任务日志):\n\`\`\`$(grep -v '任务' $TMPDIR/ShellCrash.log |tail -n 20)\`\`\`" sleep 3 send_menu continue ;; "transport") send_transport_menu continue ;; "set_sub") echo "await_sub" > "$STATE_FILE" send_msg "✏ 请输入新的订阅链接:" continue ;; ts_*) transport continue ;; esac ### --- 处理订阅输入 --- ### TEXT=$(echo "$UPDATES" | grep -o '"text":"[^"]*"' | tail -n1 | sed 's/.*"text":"//;s/"$//') if [ "$(cat "$STATE_FILE" 2>/dev/null)" = "await_sub" ]; then echo "" > "$STATE_FILE" do_set_sub "$TEXT" send_msg "订阅更新完成:\n$(cat "$LOGFILE")" send_menu continue fi ### 处理命令 ### case "$TEXT" in /crash) send_menu ;; /"$my_alias") send_menu ;; /help) send_help ;; esac done } [ "$TG_menupush" = ON ] && send_menu polling