// ==UserScript==
// @name Zibzab's GameDox/Rom Upload Helper
// @namespace http://tampermonkey.net/
// @version 1.3
// @description try to take over the world :)
// @author BestGrapeLeaves
// @match https://gazellegames.net/upload.php?groupid=*
// @icon https://i.imgur.com/UFOk0Iu.png
// @grant GM_xmlhttpRequest
// @connect datomatic.no-intro.org
// @license MIT
// ==/UserScript==
const GAME_DOX_INSERT = `[align=center] pdf pages
[/align]
`;
const genRomInsert = (
url = "xxx",
filename = "xxx"
) => `[align=center]${filename} matches [url=${url}]No-Intro checksum[/url]
Compressed with [url=https://sourceforge.net/projects/trrntzip/]torrentzip.[/url][/align]
`;
const regionToLanguage = {
USA: "English",
Europe: "English",
Japan: "Japanese",
World: "English",
"USA, Europe": "English",
Other: "English",
};
const twoLetterLanguageCodeToGGn = {
en: "English",
de: "German",
fr: "French",
cz: "Czech",
zh: "Chinese",
it: "Italian",
ja: "Japanese",
ko: "Korean",
pl: "Polish",
pt: "Portuguese",
ru: "Russian",
es: "Spanish",
};
const parseLanguage = (region, possiblyLanguages) => {
if (possiblyLanguages === undefined) {
return regionToLanguage[region] || "Other";
}
const twoLetterCodes = possiblyLanguages
.split(",")
.map((l) => l.trim().toLowerCase());
const isLanguages = twoLetterCodes.every((l) => l.length === 2);
if (!isLanguages || twoLetterCodes.length === 0) {
return regionToLanguage[region] || "Other";
}
if (twoLetterCodes.length > 1) {
return "Multi-Language";
}
return twoLetterLanguageCodeToGGn[twoLetterCodes[0]] || "Other";
};
function noIntroUI() {
// elements
const noIntroContainer = $(
`<tr id="no-intro-url" name="no-intro-url">
<td class="label">No-Intro Link</td>
</tr>`
);
const noIntroInput = $(
'<input type="text" id="no-intro-url-input" name="no-intro-url-input" size="70%" class="input_tog" value="">'
);
const noIntroError = $(
'<p id="no-intro-url-error" name="no-intro-url-error" style="color: red; white-space:pre-line;"></p>'
).hide();
const noIntroLoading = $(
'<p id="no-intro-url-loading" name="no-intro-url-loading" style="color: green;">Loading...</p>'
).hide();
// structure
const td = $("<td></td>");
td.append(noIntroInput);
td.append(noIntroError);
td.append(noIntroLoading);
noIntroContainer.append(td);
// utils
const error = (msg) => {
noIntroError.text(msg);
noIntroError.show();
};
const loading = (isLoading) => {
if (isLoading) {
noIntroLoading.show();
} else {
noIntroLoading.hide();
}
};
return { loading, error, noIntroContainer, noIntroInput, noIntroError };
}
(function () {
"use strict";
const { noIntroContainer, noIntroInput, noIntroError, error, loading } =
noIntroUI();
// handle url
let justChecked = "";
const submitNoInput = () => {
noIntroError.hide();
const url = noIntroInput.val();
if (justChecked === url) {
return;
}
if (!url.startsWith("https://datomatic.no-intro.org/")) {
error("Invalid URL");
return;
}
justChecked = url;
loading(true);
GM_xmlhttpRequest({
method: "GET",
url,
timeout: 5000,
onload: ({ responseText }) => {
try {
const parser = new DOMParser();
const scraped = parser.parseFromString(responseText, "text/html");
// HTML is great
const filename = scraped
.querySelector("td.TableTitle")
.parentElement.parentElement.parentElement.nextElementSibling.querySelector(
"table > tbody > tr:nth-child(2) > td:last-child"
)
.innerText.trim();
const title = scraped
.querySelector("tr.romname_section > td")
.innerText.trim();
const parenMatches = title
.match(/\(.+?\)/g)
.map((p) => p.slice(1, -1));
const [region, possiblyLanguages] = parenMatches;
const matchedGGnRegion =
php_torrent_form_regions.find((r) => r === region) || "Other";
const matchedGGnLanguage = parseLanguage(
matchedGGnRegion,
possiblyLanguages
);
$("textarea#release_desc").val(genRomInsert(url, filename));
$("select#region").val(matchedGGnRegion);
$("select#language").val(matchedGGnLanguage);
loading(false);
} catch (err) {
loading(false);
error(
"Failed to parse no-intro :/\nPlease report to BestGrapeLeaves,\nthe error was logged to the browser console"
);
console.error("zibzab helper failed to parse no-intro:", err);
}
},
ontimeout: () => {
loading(false);
error("Request to no-intro timed out after 5 seconds");
},
});
};
// bind events
noIntroInput.on("paste", (e) => {
e.preventDefault();
const text = e.originalEvent.clipboardData.getData("text/plain");
noIntroInput.val(text);
submitNoInput();
});
noIntroInput.blur(submitNoInput);
$("select#miscellaneous").change(function () {
const selected = $("select#miscellaneous option:selected").text();
if (selected === "GameDOX") {
noIntroContainer.detach();
$("input#release_title").val(
$("input#release_title").val() + " - Manual"
);
$("select#gamedox").val("Guide").change();
$("select#format").val("PDF").change();
$("input#scan").click();
Scan();
$("textarea#release_desc").val(
$("textarea#release_desc").val() + GAME_DOX_INSERT
);
} else if (selected === "ROM") {
// const url = prompt("Please enter the ROM's No-Intro link:");
noIntroContainer.insertBefore("#regionrow");
$("textarea#release_desc").val(genRomInsert());
} else {
noIntroContainer.detach();
}
});
})();