Greasy Fork

GGn vndb uploady new

gazellegames vndb uploady. input game title in game title field or vndb id (anything with v(digits)) and click vndb to fill

目前为 2023-08-02 提交的版本。查看 最新版本

// ==UserScript==
// @name         GGn vndb uploady new
// @namespace    none
// @version      1
// @description  gazellegames vndb uploady. input game title in game title field or vndb id (anything with v(digits)) and click vndb to fill
// @author       ingts
// @match        https://gazellegames.net/upload.php*
// @connect      api.vndb.org/kana
// @icon         none
// @grant        GM_xmlhttpRequest
// ==/UserScript==
'use strict';

const autoTitleCase = true
const autoSearchTrailer = true
const autoPTPimg = true

const tagsDictionary = {
    'romance': ["Love", "Polyamory", "Polygamy", "Swinging", "Romance"],
    'horror': ["Horror", "Graphic Violence"],
    'science.fiction': ["Science Fiction", "AI"],
    'drama': ["Drama", "Suicide", "Suicidal", "Desperation"],
    'crime': ["Crime", "Slave"],
    'mystery': ["Mystery"],
    'comedy': ["Comedy", "Slapstick"],
    'fantasy': ["Fantasy", "Magic", "Mahou", "Superpowers"]
}
const tagExclusions = {
    'romance': ["No Romance Plot"]
};


/* To Title Case © 2018 David Gouch | https://github.com/gouch/to-title-case */
// eslint-disable-next-line no-extend-native
String.prototype.toTitleCase = function () {
  var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i
  var alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/
  var wordSeparators = /([ :–—-])/

  return this.split(wordSeparators)
    .map(function (current, index, array) {
      if (
        /* Check for small words */
        current.search(smallWords) > -1 &&
        /* Skip first and last word */
        index !== 0 &&
        index !== array.length - 1 &&
        /* Ignore title end and subtitle start */
        array[index - 3] !== ':' &&
        array[index + 1] !== ':' &&
        /* Ignore small words that start a hyphenated phrase */
        (array[index + 1] !== '-' ||
          (array[index - 1] === '-' && array[index + 1] === '-'))
      ) {
        return current.toLowerCase()
      }

      /* Ignore URLs */
      if (array[index + 1] === ':' && array[index + 2] !== '') {
        return current
      }

      /* Capitalize the first letter */
      return current.replace(alphanumericPattern, function (match) {
        return match.toUpperCase()
      })
    })
    .join('')
}

function replaceTildeAndDash(title) {
    if (title.includes('~')) {
        return title.replace(/ ~ /g, ': ').replace(/ ~/g, ': ').replace(/~$/g, '').replace(/ ~$/g, '');
    } else if (title.includes('-')) {
        return title.replace(/ - /g, ': ').replace(/ -/g, ': ').replace(/-$/g, '');
    } else {
        return title;
    }
}

function removeLastBracket(str) {
    if (!str.endsWith(']')) return str

    let i = str.length - 1
    let bracketCounter = 0;
    for (; i >= 0; i--) {
        if (str[i] === ']') {
            bracketCounter++;
        } else if (str[i] === '[') {
            bracketCounter--;
            if (bracketCounter === 0) {
                break;
            }
        }
    }
    return str.substring(0, i).trim();
}

const gameTitleInput = document.getElementById('title');
gameTitleInput.insertAdjacentHTML("afterend", '<a href="javascript:" id="fill_vndb">vndb</a>');
const fill_vndb = document.getElementById('fill_vndb')

function fill(results) {
    document.getElementById('platform').value = 'Windows'
    const englishTitle = results.titles.find(a => a.lang === 'en')
    if (englishTitle) {
        if (autoTitleCase) gameTitleInput.value = replaceTildeAndDash(englishTitle.title).toLowerCase().toTitleCase()
        else replaceTildeAndDash(englishTitle.title)
    } else {
        if (autoTitleCase) gameTitleInput.value = results.title
        else gameTitleInput.value = results.title.toLowerCase().toTitleCase()
    }
    if (autoSearchTrailer) window.open(`https://www.youtube.com/results?search_query=${gameTitleInput.value} trailer`, '_blank').focus()

    document.getElementById('aliases').value = [results.alttitle, results.aliases.join(", ")].filter(Boolean).join(', ')


    const tagsInput = document.getElementById('tags')
    let foundTags = []
    Object.keys(tagsDictionary).forEach(ggnTag => {
        const words = tagsDictionary[ggnTag];
        let exclude = false;
        if (tagExclusions.hasOwnProperty(ggnTag)) {
            results.tags.forEach(tag => {
                tagExclusions[ggnTag].forEach(exclusion => {
                    if (tag.name.includes(exclusion)) {
                        exclude = true;
                    }
                });
            });
        }
        if (!exclude) {
            results.tags.forEach(tag => {
                words.forEach(word => {
                    if (tag.name.includes(word) && !foundTags.includes(ggnTag)) {
                        foundTags.push(ggnTag);
                    }
                });
            });
        }
    });
    foundTags.length === 0 ? tagsInput.value = 'visual.novel'
        : tagsInput.value = `visual.novel, ${foundTags.join(', ')}`

    if (results.released === 'TBA') document.getElementById('year').value = new Date().getFullYear();
    else document.getElementById('year').value = results.released.split('-')[0]


    GM_xmlhttpRequest({
        method: 'POST',
        url: 'https://api.vndb.org/kana/release',
        headers: {'Content-Type': 'application/json'},
        data: JSON.stringify({
            "filters": ["vn", "=", ["id", "=", results.id]],
            "fields": "minage, has_ero",
            "results": 100
        }),
        responseType: "json",
        onload: function (response) {
            let ratingSelectValue
            const highestMinAge = Math.max(...response.response.results.map(result => result.minage));
            if (highestMinAge === 12 || highestMinAge === 13) ratingSelectValue = 5
            else if (highestMinAge === 16 || highestMinAge === 17) ratingSelectValue = 7
            else if (highestMinAge >= 18) ratingSelectValue = 9
            else ratingSelectValue = 13
            document.getElementById('Rating').value = ratingSelectValue
            if (response.response.results.some(r => r.has_ero))
                tagsInput.value += ', adult'
        }
    })


    document.getElementById('image').value = results.image.url
    if (autoPTPimg) document.getElementById('image').nextElementSibling.click()

    const systemRequirements = `
[quote][align=center][b][u]System Requirements[/u][/b][/align]
[*][b]OS[/b]:
[*][b]Processor[/b]:
[*][b]Memory[/b]:
[*][b]Graphics[/b]:
[*][b]DirectX[/b]:
[*][b]Storage[/b]: [/quote]`
    document.getElementById('album_desc').value =
        `[align=center][b][u]About the game[/u][/b][/align]
${removeLastBracket(results.description)}
${systemRequirements}
`
    if (results.platforms.some(p => !['win', 'lin', 'mac'].includes(p))) {
        fill_vndb.removeEventListener('click', firstClick)
        fill_vndb.textContent = 'console version found. remove system requirements?'
        fill_vndb.addEventListener('click', () => {
            document.getElementById('album_desc').value = document.getElementById('album_desc').value.replace(systemRequirements, '')
            fill_vndb.outerHTML = '<span>removed</span>'
        })
    }

    const screens = document.getElementsByName("screens[]");
    const add_screen = document.querySelector("#image_block a[href='#']");
    results.screenshots.forEach(function (screen, index) {
        if (index >= 20) return;
        if (index >= 4) add_screen.click();
        screens[index].value = screen.url;
        if (autoPTPimg) screens[index].nextElementSibling.click()
    });

}

function firstClick() {
    if (gameTitleInput.value !== "") {
        let vndbFilter;
        const linkmatch = gameTitleInput.value.match(/v(\d+)/)
        linkmatch ? vndbFilter = ["id", "=", `${linkmatch[1]}`] : vndbFilter = ["search", "=", `${gameTitleInput.value}`]
        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://api.vndb.org/kana/vn',
            headers: {'Content-Type': 'application/json'},
            data: JSON.stringify({
                "filters": vndbFilter,
                "fields": "alttitle, titles.title, title, aliases, description, image.url, screenshots.url, released, titles.lang, tags.name, platforms",
                "results": 1
            }),
            responseType: "json",
            onload: function (response) {
                fill(response.response.results[0])
            }
        })
    }
}
fill_vndb.addEventListener('click', firstClick)