Skip to content

Commit 6803b8a

Browse files
justchokingaround71zenithPlexTDM
authored
fix: update api_resp req including query_hash and origin, and add filemoon provider (#1691)
Co-authored-by: zen <71zenith@proton.me> Co-authored-by: PlexTDM <tengisteka0631@gmail.com>
1 parent 766795b commit 6803b8a

1 file changed

Lines changed: 64 additions & 7 deletions

File tree

ani-cli

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
version_number="4.13.0"
3+
version_number="4.14.0"
44

55
# UI
66

@@ -181,9 +181,14 @@ generate_link() {
181181
1) provider_init "wixmp" "/Default :/p" ;; # wixmp(default)(m3u8)(multi) -> (mp4)(multi)
182182
2) provider_init "youtube" "/Yt-mp4 :/p" ;; # youtube(mp4)(single)
183183
3) provider_init "sharepoint" "/S-mp4 :/p" ;; # sharepoint(mp4)(single)
184+
5) provider_init "filemoon" "/Fm-mp4 :/p" ;; # filemoon(m3u8)(single)
184185
*) provider_init "hianime" "/Luf-Mp4 :/p" ;; # hianime(m3u8)(multi)
185186
esac
186-
[ -n "$provider_id" ] && get_links "$provider_id"
187+
if [ "$1" = "5" ] && [ -n "$provider_id" ]; then
188+
get_filemoon_links "$provider_id"
189+
else
190+
[ -n "$provider_id" ] && get_links "$provider_id"
191+
fi
187192
}
188193

189194
select_quality() {
@@ -220,13 +225,66 @@ decode_tobeparsed() {
220225
printf '%s' "$plain" | tr '{}' '\n' | sed -nE 's|.*"sourceUrl":"--([^"]*)".*"sourceName":"([^"]*)".*|\2 :\1|p'
221226
}
222227

228+
b64url_to_hex() {
229+
_len=$(printf '%s' "$1" | wc -c | tr -d ' ')
230+
_mod=$((_len % 4))
231+
case $_mod in
232+
2) _pad="==" ;;
233+
3) _pad="=" ;;
234+
*) _pad="" ;;
235+
esac
236+
printf '%s%s' "$1" "$_pad" | tr -- '-_' '+/' | base64 -d | od -A n -t x1 | tr -d ' \n'
237+
}
238+
239+
get_filemoon_links() {
240+
response="$(curl -e "$allanime_refr" -s "https://${allanime_base}$1" -A "$agent")"
241+
_fm_json="$(printf '%s' "$response" | tr -d '\n ' | tr ',' '\n')"
242+
iv="$(printf '%s' "$_fm_json" | sed -nE 's|^"iv":"([^"]*)"$|\1|p')"
243+
payload="$(printf '%s' "$_fm_json" | sed -nE 's|^"payload":"([^"]*)"$|\1|p')"
244+
kp1="$(printf '%s' "$_fm_json" | sed -nE 's|^"key_parts":\["([^"]*)"$|\1|p')"
245+
kp2="$(printf '%s' "$_fm_json" | sed -nE 's|^"([A-Za-z0-9_-]+)"\]$|\1|p' | head -1)"
246+
_kp1_hex="$(b64url_to_hex "$kp1")"
247+
_kp2_hex="$(b64url_to_hex "$kp2")"
248+
key_hex="$_kp1_hex$_kp2_hex"
249+
iv_hex="$(b64url_to_hex "$iv")00000002"
250+
tmp="$(mktemp)"
251+
_fm_len=$(printf '%s' "$payload" | wc -c | tr -d ' ')
252+
_fm_mod=$((_fm_len % 4))
253+
case $_fm_mod in
254+
2) _fm_pad="==" ;;
255+
3) _fm_pad="=" ;;
256+
*) _fm_pad="" ;;
257+
esac
258+
printf '%s%s' "$payload" "$_fm_pad" | tr -- '-_' '+/' | base64 -d >"$tmp"
259+
ct_len=$(($(wc -c <"$tmp") - 16))
260+
plain="$(dd if="$tmp" bs=1 count="$ct_len" 2>/dev/null | openssl enc -d -aes-256-ctr -K "$key_hex" -iv "$iv_hex" -nosalt -nopad 2>/dev/null)"
261+
rm -f "$tmp"
262+
printf '%s' "$plain" | tr '{}[]' '\n' |
263+
sed -nE 's|.*"url":"([^"]*)".*"height":([0-9]+).*|\2 >\1|p;s|.*"height":([0-9]+).*"url":"([^"]*)".*|\1 >\2|p' |
264+
sed 's|\\u0026|\&|g;s|\\u003D|=|g' | sort -rn
265+
printf "\033[1;32m%s\033[0m Links Fetched\n" "Filemoon" 1>&2
266+
}
267+
223268
# gets embed urls, collects direct links into provider files, selects one with desired quality into $episode
224269
get_episode_url() {
225-
# get the embed urls of the selected episode
226270
#shellcheck disable=SC2016
227271
episode_embed_gql='query ($showId: String!, $translationType: VaildTranslationTypeEnumType!, $episodeString: String!) { episode( showId: $showId translationType: $translationType episodeString: $episodeString ) { episodeString sourceUrls }}'
228272

229-
api_resp="$(curl -e "$allanime_refr" -s -H "Content-Type: application/json" -X POST "${allanime_api}/api" --data "{\"variables\":{\"showId\":\"$id\",\"translationType\":\"$mode\",\"episodeString\":\"$ep_no\"},\"query\":\"$episode_embed_gql\"}" -A "$agent")"
273+
query_hash="d405d0edd690624b66baba3068e0edc3ac90f1597d898a1ec8db4e5c43c00fec"
274+
query_vars="{\"showId\":\"$id\",\"translationType\":\"$mode\",\"episodeString\":\"$ep_no\"}"
275+
query_ext="{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"$query_hash\"}}"
276+
277+
encoded_vars=$(printf '%s' "$query_vars" | sed 's/"/%22/g; s/:/%3A/g; s/{/%7B/g; s/}/%7D/g; s/,/%2C/g')
278+
encoded_ext=$(printf '%s' "$query_ext" | sed 's/"/%22/g; s/:/%3A/g; s/{/%7B/g; s/}/%7D/g; s/,/%2C/g; s/ /%20/g')
279+
280+
api_url="${allanime_api}/api?variables=${encoded_vars}&extensions=${encoded_ext}"
281+
282+
api_resp="$(curl -e "https://youtu-chan.com" -s -A "$agent" -H "Origin: https://youtu-chan.com" "$api_url")"
283+
284+
if [ -z "$api_resp" ] || ! printf "%s" "$api_resp" | grep -q "tobeparsed"; then
285+
api_resp="$(curl -e "$allanime_refr" -s -H "Content-Type: application/json" -X POST "${allanime_api}/api" --data "{\"variables\":{\"showId\":\"$id\",\"translationType\":\"$mode\",\"episodeString\":\"$ep_no\"},\"query\":\"$episode_embed_gql\"}" -A "$agent")"
286+
fi
287+
230288
if printf "%s" "$api_resp" | grep -q '"tobeparsed"'; then
231289
blob="$(printf "%s" "$api_resp" | sed -nE 's|.*"tobeparsed":"([^"]*)".*|\1|p')"
232290
resp="$(decode_tobeparsed "$blob")"
@@ -235,7 +293,7 @@ get_episode_url() {
235293
fi
236294
# generate links into sequential files
237295
cache_dir="$(mktemp -d)"
238-
providers="1 2 3 4"
296+
providers="1 2 3 4 5"
239297
for provider in $providers; do
240298
generate_link "$provider" >"$cache_dir"/"$provider" &
241299
done
@@ -423,8 +481,7 @@ exit_after_play="${ANI_CLI_EXIT_AFTER_PLAY:-0}"
423481
use_external_menu="${ANI_CLI_EXTERNAL_MENU:-0}"
424482
external_menu_normal_window="${ANI_CLI_EXTERNAL_MENU_NORMAL_WINDOW:-0}"
425483
skip_intro="${ANI_CLI_SKIP_INTRO:-0}"
426-
# shellcheck disable=SC2154
427-
skip_title="$ANI_CLI_SKIP_TITLE"
484+
skip_title="${ANI_CLI_SKIP_TITLE:-}"
428485
[ -t 0 ] || (command -v dmenu && use_external_menu=2)
429486
[ -t 0 ] || (command -v rofi && use_external_menu=1)
430487
hist_dir="${ANI_CLI_HIST_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/ani-cli}"

0 commit comments

Comments
 (0)