ملخص المباراة رقم 2
addEventListener('fetch', event => {
event.respondWith(handleRequest(event))
})
async function handleRequest(event) {
const request = event.request
const url = new URL(request.url)
const allowedDomain = "123tv.fun"
const referer = request.headers.get("referer") || ""
const host = url.hostname
if (!referer.includes(allowedDomain) && !referer.includes(host)) {
return new Response("Access Denied",{status:403})
}
const windowsUA =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
const fixedReferer="https://beinmatch11.com"
const fixedOrigin="https://beinmatch11.com"
// =====================
// 🔥 FINAL RESOLVER (FIXED)
// =====================
async function resolveFinalUrl(target){
let current = target
for(let i=0;i<5;i++){
const res = await fetch(current,{
method:"GET",
redirect:"manual",
headers:{
"User-Agent":windowsUA,
"Referer":fixedReferer,
"Origin":fixedOrigin,
"Accept":"*/*"
}
})
if(res.status>=300 && res.status<400){
const loc = res.headers.get("Location")
if(!loc) break
current = loc
}else{
break
}
}
return current
}
// ============ MASTER ============
if(url.pathname==="/master.m3u8"){
const list=url.searchParams.get("list")
if(!list)
return new Response("No stream list",{status:400})
const streams=decodeURIComponent(list).split("|")
let master="#EXTM3U\n\n"
streams.forEach((s,i)=>{
let bw=450000
let res="426x240"
if(i==0){bw=1800000;res="1024x576"}
if(i==1){bw=900000;res="640x360"}
if(i==2){bw=450000;res="426x240"}
master+=`#EXT-X-STREAM-INF:BANDWIDTH=${bw},RESOLUTION=${res}\n`
master+=`${url.origin}?proxy=${encodeURIComponent(s)}&mode=1\n\n`
})
return new Response(master,{
headers:{
"Content-Type":"application/vnd.apple.mpegurl",
"Access-Control-Allow-Origin":"*",
"Cache-Control":"no-store"
}
})
}
// ============ SEGMENT ============
if(url.pathname.startsWith("/segment/")){
const segName=decodeURIComponent(url.pathname.split("/segment/")[1])
const cache=caches.default
const cacheKey=new Request(url.toString())
let cached=await cache.match(cacheKey)
if(cached) return cached
const mapKey=new Request("https://segment-map")
const saved=await cache.match(mapKey)
if(!saved)
return new Response("No segment map",{status:500})
const map=await saved.json()
const originalUrl=map[segName]
if(!originalUrl)
return new Response("Segment not found",{status:404})
const r=await fetch(originalUrl,{
headers:{
"User-Agent":windowsUA,
"Referer":fixedReferer,
"Origin":fixedOrigin,
"Accept":"*/*"
}
})
const resp=new Response(r.body,{
status:r.status,
headers:{
"Content-Type": originalUrl.includes(".js")
?"application/javascript"
:"video/mp2t",
"Access-Control-Allow-Origin":"*",
"Cache-Control":"public,max-age=180"
}
})
await cache.put(cacheKey,resp.clone())
return resp
}
// ============ PROXY (FIXED) ============
if(url.searchParams.get("proxy")){
const target=url.searchParams.get("proxy")
const mode=url.searchParams.get("mode")
const cache=caches.default
const key=new Request("final-url::"+target)
// 🔥 جلب من الكاش
let cachedFinal = await cache.match(key)
let finalUrl = target
if(cachedFinal){
finalUrl = await cachedFinal.text()
}
// 🔥 حل redirect الحقيقي
finalUrl = await resolveFinalUrl(finalUrl)
// 🔥 تثبيت الرابط النهائي
await cache.put(key,new Response(finalUrl))
// 🔥 طلب البث
const response = await fetch(finalUrl,{
headers:{
"User-Agent":windowsUA,
"Referer":fixedReferer,
"Origin":fixedOrigin,
"Accept":"*/*"
}
})
const type=response.headers.get("content-type")||""
if((target.includes(".m3u8")||target.includes(".json")) && mode==="1"){
const text=await response.text()
const mapKey=new Request("https://segment-map")
const old=await cache.match(mapKey)
let map = old ? await old.json() : {}
const rewritten=text.split("\n").map(line=>{
if(line.startsWith("#")||!line.trim())
return line
const full=line.startsWith("http")
?line
:new URL(line,finalUrl).href
const segName=full.split("/").pop().split("?")[0]
map[segName]=full
return `${url.origin}/segment/${segName}`
}).join("\n")
await cache.put(mapKey,new Response(JSON.stringify(map)))
return new Response(rewritten,{
headers:{
"Content-Type":"application/vnd.apple.mpegurl",
"Access-Control-Allow-Origin":"*",
"Cache-Control":"no-store"
}
})
}
return new Response(response.body,{
status:response.status,
headers:{
"Content-Type":type,
"Access-Control-Allow-Origin":"*"
}
})
}
// ============ PLAYER ============
const video0Url=url.searchParams.get("video0")
const video1Url=url.searchParams.get("video1")
let proxiedUrl=""
let playerType="plyr"
if(video0Url){
playerType="videojs"
if(video0Url.includes("|")){
proxiedUrl=`${url.origin}/master.m3u8?list=${encodeURIComponent(video0Url)}`
}else{
proxiedUrl=`${url.origin}?proxy=${encodeURIComponent(video0Url)}&mode=1`
}
}else if(video1Url){
playerType="plyr"
if(video1Url.includes("|")){
proxiedUrl=`${url.origin}/master.m3u8?list=${encodeURIComponent(video1Url)}`
}else{
proxiedUrl=`${url.origin}?proxy=${encodeURIComponent(video1Url)}&mode=1`
}
}else{
proxiedUrl=`${url.origin}?proxy=${encodeURIComponent("https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8")}&mode=1`
}
// ============ HTML ============
return new Response(`
`,{
headers:{
"Content-Type":"text/html;charset=UTF-8",
"Content-Security-Policy":
"frame-ancestors https://www.123tv.fun"
}
})
}