// ==UserScript==
// @name Steam🎮-100%
// @name:ar ستيم 🎮-100%
// @name:bg Steam🎮-100%
// @name:cs Steam🎮-100%
// @name:da Steam🎮-100%
// @name:de Steam🎮-100%
// @name:el Steam🎮-100%
// @name:en Steam🎮-100%
// @name:es Steam🎮-100%
// @name:fi Steam🎮-100%
// @name:fr Steam🎮-100%
// @name:fr-CA Steam🎮-100%
// @name:he סטים 🎮-100%
// @name:hu Steam🎮-100%
// @name:id Steam🎮-100%
// @name:it Steam🎮-100%
// @name:ja スチーム🎮-100%
// @name:ko 스팀🎮-100%
// @name:nl Steam🎮-100%
// @name:no Steam🎮-100%
// @name:pl Steam🎮-100%
// @name:pt Steam🎮-100%
// @name:ro Steam🎮-100%
// @name:ru Steam🎮-100%
// @name:sk Steam🎮-100%
// @name:sv Steam🎮-100%
// @name:th สตีม🎮-100%
// @name:tr Steam🎮-100%
// @name:uk Steam🎮-100%
// @name:vi Steam🎮-100%
// @name:zh Steam🎮-100%
// @description Steam -100% with semi-auto-download for IGG
// @description:ar ستيم -100٪ مع تحميل شبه تلقائي لـ IGG
// @description:bg Steam -100% със полуавтоматично изтегляне за IGG
// @description:cs Steam -100% s poloautomatickým stahováním pro IGG
// @description:da Steam -100% med semi-automatisk download til IGG
// @description:de Steam -100% mit halbautomatischem Download für IGG
// @description:el Steam -100% με ημι-αυτόματη λήψη για IGG
// @description:en Steam -100% with semi-auto-download for IGG
// @description:es Steam -100% con descarga semi-automática para IGG
// @description:fi Steam -100% puoliautomaattisella latauksella IGG:lle
// @description:fr Steam -100% avec semi-téléchargement automatique pour IGG
// @description:fr-CA Steam -100% avec semi-téléchargement automatique pour IGG
// @description:he Steam -100% עם הורדה חצי-אוטומטית עבור IGG
// @description:hu Steam -100% félautomatikus letöltéssel IGG-hez
// @description:id Steam -100% dengan unduhan semi-otomatis untuk IGG
// @description:it Steam -100% con download semi-automatico per IGG
// @description:ja Steam -100%:IGG用の半自動ダウンロード対応
// @description:ko Steam -100% IGG용 반자동 다운로드 지원
// @description:nl Steam -100% met semi-automatische download voor IGG
// @description:no Steam -100% med semi-automatisk nedlasting for IGG
// @description:pl Steam -100% z półautomatycznym pobieraniem dla IGG
// @description:pt Steam -100% com semi-download automático para IGG
// @description:ro Steam -100% cu descărcare semi-automată pentru IGG
// @description:ru Steam -100% с полуавтоматической загрузкой для IGG
// @description:sk Steam -100% s poloautomatickým sťahovaním pre IGG
// @description:sv Steam -100% med semi-automatisk nedladdning för IGG
// @description:th Steam -100% พร้อมการดาวน์โหลดกึ่งอัตโนมัติสำหรับ IGG
// @description:tr Steam -100% IGG için yarı otomatik indirme ile
// @description:uk Steam -100% з напівавтоматичним завантаженням для IGG
// @description:vi Steam -100% với tải xuống bán tự động cho IGG
// @description:zh Steam -100%,支持 IGG 半自动下载
// @version 1.1.2
// @match *store.steampowered.com/app/*
// @include *igg-games.com/*-free-download.html?cdl*
// @include *skidrowreloaded.com/*&z123*
// @match https://online-fix.me/index.php?do=search*
// @run-at document-end
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addValueChangeListener
// @grant GM_xmlhttpRequest
// @connect skidrowreloaded.com
// @connect online-fix.me
// @license MIT
// @namespace DEV314R
// ==/UserScript==
(function() {
"use strict";
// ---------- labels ----------
const LABEL_DL={
en:"Download",ar:"تحميل",bg:"Изтегли",
"zh-CN":"下载","zh-TW":"下載",
cs:"Stáhnout",da:"Download",nl:"Downloaden",
fi:"Lataa", fr:"Télécharger",de:"Herunterladen",
el:"Λήψη",hu:"Letöltés", id:"Unduh",
it:"Scarica",ja:"ダウンロード",ko:"다운로드",
no:"Last ned",pl:"Pobierz",
"pt-PT":"Transferir","pt-BR":"Baixar",
ro:"Descărcare", ru:"Скачать",
"es-ES":"Descargar","es-LA":"Bajar",
sv:"Ladda ner", th:"ดาวน์โหลด", tr:"İndir",
uk:"Завантажити", vi:"Tải xuống"
};
const LABEL_MULTI={
en:"Multiplayer",ar:"متعدد اللاعبين",bg:"Мултиплейър",
"zh-CN":"多人游戏","zh-TW":"多人遊戲",
cs:"Multiplayer",da:"Flerspiller", nl:"Multiplayer",
fi:"Moninpeli",fr:"Multijoueur",de:"Mehrspieler",
el:"Πολλαπλών παικτών", hu:"Többjátékos",id:"Multipemain",
it:"Multigiocatore",ja:"マルチプレイヤー",ko:"멀티플레이어",
no:"Flerspiller",pl:"Wieloosобowy",
"pt-PT":"Multijogador","pt-BR":"Multijogador",
ro:"Multiplayer",ru:"Многопользовательская игра",
"es-ES":"Multijugador","es-LA":"Multijugador",
sv:"Flerspelarläge",th:"ผู้เล่นหลายคน", tr:"Çok Oyunculu",
uk:"Багатокористувацька",vi:"Nhiều người chơi"
};
const lang=navigator.language.toLowerCase();
const langKey=(()=>{if(lang.startsWith("pt-br"))return"pt-BR";if(lang.startsWith("pt-pt"))return"pt-PT";
if(lang.startsWith("zh-tw")||lang.startsWith("zh-hk"))return"zh-TW";if(lang.startsWith("zh"))return"zh-CN";
if(lang.startsWith("es-"))return["es-mx","es-ar","es-co","es-cl","es-pe","es-ve","es-uy","es-bo","es-py","es-cr","es-pa","es-do","es-ec","es-gt","es-hn","es-ni","es-sv","es-pr","es-419"].includes(lang)?"es-LA":"es-ES";
return lang.split("-")[0];})();
const dlLabel=LABEL_DL[langKey]||LABEL_DL.en;
const multiLabel=LABEL_MULTI[langKey]||LABEL_MULTI.en;
// ---------- base utils ----------
const normBase=s=>s.normalize("NFD").replace(/[\u0300-\u036f]|[©®™℠]|\?/g,"").replace(/[:'–—]/g,"").trim().toLowerCase();
const slugify=s=>normBase(s).replace(/\s+/g,"-");
const qEncode=s=>encodeURIComponent(s);
// ---------- platform ----------
const defaultData={IGG:{source:"1Fichier"},Skidrow:{source:"MEGA"},FitGirl:{source:"DataNodes"}};
let platformData=GM_getValue("platformData",defaultData);
let platform=GM_getValue("platform","Skidrow");
if(!platformData[platform])platformData[platform]={source:defaultData[platform].source};
GM_setValue("platformData",platformData);
let sdl=platformData[platform].source;
function setPlatform(p){
platform=p;
GM_setValue("platform",platform);
if(!platformData[platform])platformData[platform]={source:defaultData[platform].source};
sdl=platformData[platform].source;
GM_setValue("platformData",platformData);
renderSourceFlyout();
updateDownloadLink(true);
}
function setSourceForPlatform(src){
platformData[platform]={source:src};
GM_setValue("platformData",platformData);
sdl=src;
}
// ---------- style ----------
const style=document.createElement("style");
style.textContent=`
.menu{font-family:Arial,sans-serif;font-size:1em;position:relative;user-select:none;padding:.1em;display:inline-flex}
.menu-btn{background:#67c1f533;color:#67c1f5;padding:.4em .6em;border-radius:.3em;cursor:pointer}
.menu-btn:hover{background:#67c1f5bb;color:#fff}
.flyout{border:none;border-radius:.3em;background:#23262E;position:absolute;top:100%;left:0;display:none;z-index:10000}
.menu:hover .flyout{display:block}
.flyout a{display:block;padding:.4em .6em;background:#23262E;color:#ddd;text-decoration:none}
.flyout a:hover{background:#85949d59;color:#fff}
.menu-container{right:.75em;top:.75em;z-index:9999;position:fixed}
`;
document.head.appendChild(style);
// ---------- gmFetch ----------
const gmFetchHTML=(url,timeout=10000)=>new Promise(resolve=>{
if(typeof GM_xmlhttpRequest!=="function"){resolve(null);return;}
let done=false;
const timer=setTimeout(()=>{if(!done){done=true;resolve(null)}},timeout);
GM_xmlhttpRequest({
method:"GET",url,
onload:r=>{if(!done){done=true;clearTimeout(timer);resolve(new DOMParser().parseFromString(r.responseText,"text/html"))}},
onerror:()=>{if(!done){done=true;clearTimeout(timer);resolve(null)}}
});
});
// ---------- game name ----------
let gameNameCache=null;
const ensureGameName=async()=>{
if(gameNameCache) return gameNameCache;
const local=document.querySelector('span[itemprop="name"]')?.textContent||document.querySelector("#appHubAppName")?.innerText||"";
if(local){gameNameCache=slugify(local);return gameNameCache;}
const doc=await gmFetchHTML(location.origin+location.pathname+"?l=english");
const name=doc?.querySelector('span[itemprop="name"]')?.textContent||"";
gameNameCache=name?slugify(name):null;
return gameNameCache;
};
// ---------- spinner ----------
function startLoadingAnim(span){
if(!span)return;
let i=0;
const f=["⠁","⠃","⠇","⠧","⠷","⠿","⠻","⠟","⠯","⠷","⠧","⠇","⠃"];
stopLoadingAnim(span,"");
span._timer=setInterval(()=>{span.textContent=f[i=++i%f.length]+" "+dlLabel},90);
}
function stopLoadingAnim(span,txt){
if(!span)return;
if(span._timer)clearInterval(span._timer);
delete span._timer;
span.textContent=txt;
}
// ---------- skidrow ----------
async function testSkidrowStepByStep(slug,enc){
if(!slug)return null;
const q=encodeURIComponent(slug);
const searchDoc=await gmFetchHTML(`https://www.skidrowreloaded.com/?s=${q}`);
if(!searchDoc)return null;
const post=[...searchDoc.querySelectorAll("[class^=post] h2 a[href]")].find(a=>a.textContent.toLowerCase().includes(slug.replace(/-/g," ").toLowerCase()));
if(!post)return null;
const postDoc=await gmFetchHTML(post.href);
if(!postDoc)return null;
return [...postDoc.querySelectorAll("[id^=tabs] p strong")].find(s=>s.textContent.toLowerCase().includes(enc.toLowerCase()))?.closest("p")?.querySelector("a")?.href||null;
}
// ---------- apply link ----------
let skidrowLinkCache=null;
const applyLink=dl=>{
if(!dl)return;
const enc=qEncode(sdl);
if(platform==="IGG"){
dl.href=`https://igg-games.com/${gameNameCache}-free-download.html?cdl&src=${enc}`;
dl.target="_blank";dl.onclick=null;
}else if(platform==="FitGirl"){
dl.href=`https://fitgirl-repacks.site/?s=${gameNameCache.replace(/-/g,"+")}&src=${enc}`;
dl.target="_blank";dl.onclick=null;
}else{
dl.href="#";dl.onclick=async e=>{
e.preventDefault();
const span=dl.querySelector("span");
if(skidrowLinkCache){window.open(skidrowLinkCache,"_blank");return;}
startLoadingAnim(span);
skidrowLinkCache=await testSkidrowStepByStep(gameNameCache,enc);
stopLoadingAnim(span,skidrowLinkCache?dlLabel:"❌➡🎯➡🔄");
if(skidrowLinkCache)window.open(skidrowLinkCache,"_blank");
};
}
};
// reset labels
document.addEventListener("click",e=>{
if(!e.target.closest(".flyout"))return;
skidrowLinkCache=null;
document.querySelectorAll(".download-btn span,#add314 span").forEach(s=>s.textContent=dlLabel);
});
// ---------- flyouts ----------
const sourcesByPlatform={
IGG:["1Fichier","MegaUp.net","Mega.nz","GoFile","Bowfile","Google Drive"],
Skidrow:["MEGA","1FICHIER","PIXELDRAIN","MEDIAFIRE","GOFILE","VIKINGFILE","BOWFILE","1CLOUDFILE"],
FitGirl:["DataNodes","FuckingFast","MultiUpload"]
};
function createFlyout(label,key,items,stars=[]){
const container=document.querySelector("#category_block");if(!container)return;
const val=key==="platform"?platform:sdl;
const div=document.createElement("div");
div.className="menu";div.dataset.type=key;
div.innerHTML=`
<div class="menu-btn">${label}: ${val}</div>
<div class="flyout">${items.map(i=>`<a href="#" data-value="${i}">${stars.includes(i)?"⭐"+i:i}</a>`).join("")}</div>
`;
container.insertAdjacentElement("beforebegin",div);
const btn=div.querySelector(".menu-btn");
div.querySelectorAll("a").forEach(a=>a.addEventListener("click",e=>{
e.preventDefault();
const v=a.dataset.value;
if(key==="platform")setPlatform(v);else setSourceForPlatform(v);
btn.textContent=`${label}: ${v}`;
updateDownloadLink(true);
}));
}
function renderSourceFlyout(){
document.querySelectorAll('.menu[data-type="source"]').forEach(n=>n.remove());
const container=document.querySelector("#category_block");if(!container)return;
const list=sourcesByPlatform[platform]||[];
const val=platformData[platform]?.source||defaultData[platform].source||list[0];
GM_setValue("platformData",platformData);
const div=document.createElement("div");
div.className="menu";div.dataset.type="source";
div.innerHTML=`
<div class="menu-btn">🎯: ${val}</div>
<div class="flyout">${list.map(i=>`<a href="#" data-value="${i}">${i}</a>`).join("")}</div>
`;
container.insertAdjacentElement("beforebegin",div);
const btn=div.querySelector(".menu-btn");
div.querySelectorAll("a").forEach(a=>a.addEventListener("click",e=>{
e.preventDefault();
const v=a.dataset.value;
setSourceForPlatform(v);
btn.textContent=`🎯: ${v}`;
updateDownloadLink(true);
}));
}
// ---------- update DL ----------
const updateDownloadLink=async(force=false)=>{
const dl=document.querySelector('#add314');if(!dl)return;
if(!force && !document.hasFocus())return;
const name=await ensureGameName();if(!name)return;
applyLink(dl);
};
// ---------- UI init ----------
const initUI=()=>{
const wrap=document.querySelector('.game_area_purchase_game_wrapper:not(#demoGameBtn) > * > .game_purchase_action');
if(!wrap||document.querySelector('.game_area_comingsoon,.game_area_bubble'))return;
if(document.querySelector(".menu-container"))return;
const cont=document.createElement("div");
cont.className="menu-container";
document.body.appendChild(cont);
createFlyout("🌐","platform",["IGG","Skidrow","FitGirl"],["IGG","Skidrow"]);
renderSourceFlyout();
const priceEl=document.querySelector("[class^='discount_original_price'],[data-price-final]");
const price=(priceEl?.innerText?.trim())||"";
const finalPrice=price?`0,--${price.slice(-1)}`:"0,00";
wrap.innerHTML=`
<div class="game_purchase_action_bg">
<div class="discount_block game_purchase_discount" data-discount="100">
<div class="discount_pct">-100%</div>
<div class="discount_prices">
<div class="discount_original_price">${price}</div>
<div class="discount_final_price">${finalPrice}</div>
</div>
</div>
<div class="btn_addtocart">
<a id="add314" class="btn_green_steamui btn_medium" href="#" target="_blank"><span>${dlLabel}</span></a>
</div>
</div>
`;
updateDownloadLink(true);
// Multijoueur check
const FixGameListInMulti=["slime rancher 2"];
const raw=document.querySelector("#appHubAppName")?.innerText||"";
const norm=raw.normalize("NFD").replace(/[\u0300-\u036f]|[\u00A9\u00AE\u2122\u2120]/g,"").replace(/:| :|'| -|\?|\./g,"").trim();
const q=norm.replace(/[\\/\s]+/g,"+");
if((document.querySelector(".game_area_details_specs_ctn[href*='category2=3']:is([href*='6'],[href*='8'],[href*='9'])")||!FixGameListInMulti.includes(norm.toLowerCase())) && raw){
const url=`https://online-fix.me/index.php?do=search&subaction=search&story=${q}`;
GM_xmlhttpRequest({
method:"GET",url,
onload:r=>{
if(r.status!==200)return;
const doc=new DOMParser().parseFromString(r.responseText,"text/html");
const titles=[...doc.querySelectorAll("h2.title")].map(el=>el.innerText.replace(/ по сети/g,"").toLowerCase());
if(!titles.some(t=>t.includes(norm.toLowerCase())))return;
const base=document.querySelector("#add314");
if(base)base.insertAdjacentHTML("afterend",`<a id="add314r" class="btn_green_steamui btn_medium" href="${url}" target="_blank"><span>${multiLabel}</span></a>`);
}
});
}
};
// ---------- SPA observe ----------
const observer=new MutationObserver(()=>{if(document.querySelector('.game_area_purchase_game_wrapper'))initUI();});
observer.observe(document.documentElement,{childList:true,subtree:true});
initUI();
// ---------- IGG auto DL ----------
if(/igg-games.+download\.html\?cdl/i.test(location.href)){
document.title="⏳"+document.title;
const temp=6000;
const tryDownload=()=>{
document.querySelectorAll("b.uk-heading-bullet").forEach(el=>{
if(el.innerText.replace(/Link\s*:?/i,"").includes(sdl)){
const links=el.parentElement.querySelectorAll("a[href]");
let i=0;
const open=()=>{if(i<links.length){links[i++].click();setTimeout(open,temp);}else setTimeout(()=>window.close(),2000);};
open();
}
});
};
tryDownload();
}
// ---------- online-fix redirect ----------
if(/online-fix.me\/index.php\?do=search/i.test(location.href)){
const titles=document.querySelectorAll('h2.title');
if(titles.length===1)titles[0].click();
}
})();