Game Uploady for Pterclub
// ==UserScript== // @name Pter Fitgirl release Uploady // @namespace https://pterclub.com/forums.php?action=viewtopic&topicid=3391 // @version 1.3.3 // @description Game Uploady for Pterclub // @author NeutronNoir, ZeDoCaixao, scatking, ccf2012, fyzzy1943 // @match https://pterclub.com/uploadgame.php* // @match https://pterclub.com/editgame.php* // @require https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js // @icon https://pterclub.com/favicon.ico // @grant GM.xmlHttpRequest // @grant GM_xmlhttpRequest // @grant unsafeWindow // ==/UserScript== const DESCR = $('#descr'); function html2bb(str) { if (!str) return ""; str = str.replace(/< *br *\/*>/g, "\n\n"); //*/ str = str.replace(/< *b *>/g, "[b]"); str = str.replace(/< *\/ *b *>/g, "[/b]"); str = str.replace(/< *u *>/g, "[u]"); str = str.replace(/< *\/ *u *>/g, "[/u]"); str = str.replace(/< *i *>/g, "[i]"); str = str.replace(/< *\/ *i *>/g, "[/i]"); str = str.replace(/< *strong *>/g, "[b]"); str = str.replace(/< *\/ *strong *>/g, "[/b]"); str = str.replace(/< *em *>/g, "[i]"); str = str.replace(/< *\/ *em *>/g, "[/i]"); str = str.replace(/< *li *>/g, "[*]"); str = str.replace(/< *\/ *li *>/g, ""); str = str.replace(/< *ul *class=\\*\"bb_ul\\*\" *>/g, ""); str = str.replace(/< *\/ *ul *>/g, ""); str = str.replace(/< *h2 *class=\"bb_tag\" *>/g, "\n[center][u][b]"); str = str.replace(/< *h[12] *>/g, "\n[center][u][b]"); str = str.replace(/< *\/ *h[12] *>/g, "[/b][/u][/center]\n"); str = str.replace(/\"/g, "\""); str = str.replace(/\&/g, "&"); str = str.replace(/< *img *src="([^"]*)".*>/g, "\n"); str = str.replace(/< *a [^>]*>/g, ""); str = str.replace(/< *\/ *a *>/g, ""); str = str.replace(/< *p *>/g, "\n\n"); str = str.replace(/< *\/ *p *>/g, ""); //Yeah, all these damn stars. Because people put spaces where they shouldn't. str = str.replace(//g, "\""); str = str.replace(//g, "\""); str = str.replace(/ +/g, " "); str = str.replace(/\n +/g, "\n"); str = str.replace(/\n\n\n+/gm, "\n\n"); str = str.replace(/\n\n\n+/gm, "\n\n"); str = str.replace(/\[\/b\]\[\/u\]\[\/align\]\n\n/g, "[/b][/u][/align]\n"); str = str.replace(/\n\n\[\*\]/g, "\n[*]"); return str; } function parseSteam(response) { var steamPage = response.responseText; // var steamPage = response; console.log(steamPage) } function parseFitgirRepack($document){ console.log($document) var info1 = $document.querySelector("div[class='entry-content'] > p:nth-child(2)" ); var info2_headerlist = $document.querySelectorAll("div[class='entry-content'] > h3" ); if (!info1) { console.log("Not found: div[class='entry-content']"); return } if (!info2_headerlist) { console.log("Not found: div[class='entry-content'] > h3[3]"); return } var info1_bb = html2bb(info1.textContent) var foundFeature = Array.from(info2_headerlist).find(gg => (gg.textContent.indexOf('Feature')>0)); // console.log(foundFeature) var info2_header_bb = html2bb(foundFeature.innerHTML); // "Repack Feature" var info2_list = foundFeature.nextSibling; while(info2_list && info2_list.nodeType != 1) { info2_list = info2_list.nextSibling; } if (!info2_list) { console.log("Not found: ul"); return } var info2_list_bb = html2bb(info2_list.innerHTML); // console.log(info2_list_bb) var dlc_bb = ''; var dlc_header = Array.from($document.querySelectorAll("b")).find(gg => (gg.textContent.indexOf("Included DLCs") != -1)); if (dlc_header) { var dlc_list = dlc_header.parentNode.nextSibling; while(dlc_list && dlc_list.nodeType != 1) { dlc_list = dlc_list.nextSibling; } if (dlc_list) { dlc_bb = html2bb(dlc_list.innerHTML); } else { console.log('found dlc anchor, not found dlc list, please check.'); } } // Assembly torrent info var output = '' + info1_bb + '\n\n\n[b]' + info2_header_bb + '[/b]\n' + info2_list_bb + '\n' if (dlc_bb != '') { output = output + '\n[b]Included DLCs:[/b]\n' + dlc_bb + '\n' } return output; } function getFitgirlTitle(doc) { var title = ''; var h3_list = doc.querySelectorAll("div[class='entry-content'] > h3"); var title_html = Array.from(h3_list).find(gg => (gg.textContent.indexOf("#") != -1)); if (!title_html) { console.log("Not found: title_html"); return title; } var title_match = title_html.innerHTML.match(/strong\>(.*)\<\/str/i); if (!title_match || title_match.length != 2) { console.log(title_html.innerHTML); console.log("title not match"); return title; } title = title_match[1].replace(/\<span.*?"\>/i, ""); title = title.replace(/\<\/span\>/i, ""); console.log(title); return title; } function get1337xUrl(doc) { // var info2_headerlist = $document.querySelectorAll("div[class='entry-content'] > h3" ); var url_e = doc.querySelector("div[class='entry-content'] > ul:nth-child(5) > li:first-child > a:first-child"); if (!url_e) { console.log("1337x url get failed: div[class='entry-content'] > ul:nth-child(5) > li:first-child > a:first-child not found."); return ''; } // console.log(url); var url = url_e.getAttribute('href'); return url.indexOf('1337x') != -1 ? url : '' } function parseSteamLanguage($document){ let table = $document.querySelector('table.game_language_options'); if(!table) return; let languages = {}; for (var r = 0; r < table.rows.length; r++) { for (var c = 0; c < table.rows[r].cells.length; c++) { if(table.rows[r].cells[c].textContent.trim() === '✔'){ let header = table.rows[0].cells[c].textContent.trim(); if(!languages[header]) { languages[header] = []; } languages[header].push(table.rows[r].cells[0].textContent.trim()); } } } let output = '' let keys = Object.keys(languages); for(var i = 0; i < keys.length; i++){ let key = keys[i]; let keygroup = [key]; if(i < keys.length - 1){ for(var iNext = i+1; iNext < keys.length; iNext){ if(areSame(languages[keys[i]], languages[keys[iNext]])) { keygroup.push(keys[iNext]); keys.splice(iNext,1); } else { iNext++; } } } const multi = languages[key].length > 1; if(keys.length === 1){ output += `[b]Language${multi ? "s": ""}[/b]: `; } else { output += `[b]${keygroup.join(' and ')} Language${multi ? "s": ""}[/b]: `; } if(multi){ let lastItem = languages[key].pop(); output += languages[key].join(', '); output += ` and ${lastItem}`; } else { output += languages[key]; } output += '\n'; } return output; } function areSame(array1, array2){ return array1.length === array2.length && array1.sort().every((value, index) => value === array2.sort()[index]) } // function editboxPart1(str) { // desc_field = "#descr"; // var hidetext = '[hide=安装步骤]\n [*]运行 \"Verify BIN files before installation.bat\" 进行MD5验证(可选)\n [*]运行 \"setup.exe\"安装游戏\n [*]开始游玩\n [*]游戏经过高压,需要一定时间才能解压完毕,请耐心等待。[/hide]'; // $(desc_field).val(hidetext + '\n\n' + str + $(desc_field).val()); // } function editboxPart2(fitgirl_info) { var text = '[hide=安装步骤]\n [*]运行 \"Verify BIN files before installation.bat\" 进行MD5验证(可选)\n [*]运行 \"setup.exe\"安装游戏\n [*]开始游玩\n [*]游戏经过高压,需要一定时间才能解压完毕,请耐心等待。[/hide]'; text = text + '\n\n[font=sans-serif]' text = text + '\n\n'; text = text + '=+=LanguageAnchor=+=' + '\n\n'; text = text + fitgirl_info; text = text + '[/font]'; desc_field = "#descr"; var origin_text = $(desc_field).val(); $(desc_field).val(text + origin_text); } function changeStatus(msg) { $('#pfru_status').html(' >>' + msg); } function parse1337Language(doc) { // console.log(doc); if (!doc) { return; } var html1 = doc.querySelector("div[class='torrent-tabs']"); if (!html1) { return; } html1 = html1.textContent; // console.log(html1); var lang = html1.match(/(Interface Language[\s\S]*?)Crack/im); if (!lang || lang.length != 2) { console.log(lang); return; } lang = lang[1].trim() .replace(/\s+/g, ' ') .replace(/Audio Language/g, '\nAudio Language') .replace(/, /g, '、') .replace(/Interface Language/g, '[b]界面语言[/b]') .replace(/Audio Language/g, '[b]音频语言[/b]') .replace(/Simplified Chinese/g, '简体中文') .replace(/Traditional Chinese/g, '繁体中文') .replace(/Chinese/g, '中文') .replace(/English/g, '英语') .replace(/Russian/g, '俄语') .replace(/German/g, '德语') .replace(/French/g, '法语') .replace(/Korean/g, '韩语') .replace(/Japanese/g, '日语') .replace(/Italian/g, '意大利语') .replace(/Turkish/g, '土耳其语') .replace(/Spanish - Latin America/g, '西班牙语-拉丁美洲') .replace(/Spanish - Spain/g, '西班牙语-西班牙') .replace(/Portuguese - Brazil/g, '葡萄牙语-巴西') .replace(/Portuguese/g, '葡萄牙语') .replace(/Thai/g, '泰语') .replace(/Arabic/g, '阿拉伯语') .replace(/Danish/g, '丹麦语') .replace(/Dutch/g, '荷兰语') .replace(/Finnish/g, '芬兰语') .replace(/Norwegian/g, '挪#语') .replace(/Polish/g, '波兰语') .replace(/Swedish/g, '瑞典语') .replace(/Catalon/g, '加泰罗尼亚语') .replace(/Greek/g, '希腊语') .replace(/Czech/g, '捷克语') .replace(/Estonian/g, '爱沙尼亚语') .replace(/Hungarian/g, '匈牙利语') .replace(/Spanish/g, '西班牙语') .replace(/Indonesian/g, '印度尼西亚语') ; console.log('1337x: ' + lang); return lang; } function replaceLangAnchor(bb_lang) { if (!bb_lang) { changeStatus('处理完成!未获取到语言!'); return; } var descr = DESCR.val().replace('=+=LanguageAnchor=+=', bb_lang.trim()); DESCR.val(descr); changeStatus('处理完成!'); } function requestUrl(urlSteam, urlFitgirl) { changeStatus('开始获取FitGirl信息...'); var bbstr; GM.xmlHttpRequest({ method: "GET", url: urlFitgirl.val(), responseType: "document", onload: function(resp) { var parser = new DOMParser (); var ajaxDoc = parser.parseFromString(resp.responseText, "text/html"); // 种子简介 bbstr = parseFitgirRepack(ajaxDoc) editboxPart2(bbstr) var lang_source = $("input[name='pfru_lang_source']:checked").val(); console.log('选择从: ' + lang_source + ' 获取游戏语言'); if (lang_source == '1337x') { var url1337x = get1337xUrl(ajaxDoc); // 获取1337x链接 if (url1337x && url1337x != '') { console.log('访问: ' + url1337x + ' 获取语言'); changeStatus('正在从1337x获取语言列表...'); GM.xmlHttpRequest({ method: 'GET', url: url1337x, onload(resp) { var ajaxDoc = new DOMParser ().parseFromString(resp.responseText, "text/html"); var bb_lang = parse1337Language(ajaxDoc); replaceLangAnchor(bb_lang); }, onerror: function(resp) { console.log(resp); changeStatus('语言获取失败!'); } }); } else { changeStatus('未获取到1337x链接...'); } } else { changeStatus('正在从steam获取语言列表...'); GM.xmlHttpRequest({ method: "GET", url: urlSteam.val(), responseType: "document", onload: function(resp){ var parser = new DOMParser (); var ajaxDoc = parser.parseFromString (resp.responseText, "text/html"); var bb_lang = parseSteamLanguage(ajaxDoc); replaceLangAnchor(bb_lang); // console.log (bbstr); }, onerror: function(resp) { console.log(resp); changeStatus('语言获取失败!'); } }); } // 获取标题 var fitgirl_title = getFitgirlTitle(ajaxDoc); // 原始标题 var game_title = $("h1#top").text().slice(0,-4).trim(); var name1 = '游戏名称: <span style="color: red">' + game_title + '</span><br>'; var name2 = 'FitGirl 原始名称: <span style="color: red">' + fitgirl_title + '</span>' + '<br>'; var $name_e = $('#name').parent(); $name_e.html(name1 + name2 + $name_e.html()); $('#name').val((fitgirl_title.replace(game_title, '').trim() + ' -FitGirl').trim()); // 游戏本体 $("#categories").find("option[value='1']").attr("selected",true); // Portable $("#format").find("option[value='4']").attr("selected",true); // 欧美 $("#team").find("option[value='4']").attr("selected",true); // 可信源 $("#vs").attr("checked",true); // console.log (bbstr); } }); } (function() { 'use strict'; const PFRU_HTML = '<tr><td>Steam URL</td><td><input style="width: 450px;" id="steamurl" /></td></tr>' + '<tr><td>FitGirl URL</td><td><input style="width: 450px;" id="fitgirlurl" /></td></tr>'; var anchor = window.location.href.includes("uploadgame") ? $("#name") : $("input[name='torrentname']"); anchor.parent().parent().after(PFRU_HTML); const steamurl = $("#steamurl"); const fitgirlurl = $("#fitgirlurl"); var lang_source_html = '<input type="radio" name="pfru_lang_source" value="1337x" checked />1337x' + '<input type="radio" name="pfru_lang_source" value="steam" />steam'; fitgirlurl.after( // '<label>替换标题:<a href="javascript:void(0);" title="勾选后获取原始标题,注意需要手动去除游戏名" style="color: red">(?)</a></label><input type="checkbox" id="pfru_get_title" />' lang_source_html + ' <input type="button" id="pfru_fill_form" value="收集信息自动填写">' + ' <span id="pfru_status"></span>'); $('#pfru_fill_form').click(function () { requestUrl(steamurl, fitgirlurl); $("#console").val("16"); }); })();