Sleazy Fork is available in English.

Hentai Heroes image viewer

Allows you to display any stage image of any harem girl, owned ones or not. Works also in event display and Places of Power. Includes zoom-in feature to display full-size girl images gallery (lightbox).

02.12.2020 itibariyledir. En son verisyonu görün.

// ==UserScript==
// @name         Hentai Heroes image viewer
// @namespace    http://tampermonkey.net/
// @version      0.94
// @description  Allows you to display any stage image of any harem girl, owned ones or not. Works also in event display and Places of Power. Includes zoom-in feature to display full-size girl images gallery (lightbox).
// @author       randomfapper34
// @match        http*://nutaku.haremheroes.com/*
// @match        http*://*.hentaiheroes.com/*
// @match        http*://*.gayharem.com/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js
// @grant        none
// ==/UserScript==

// gayharem image link head:    gh1
// hentaiharem image link head: hh2

var $ = window.jQuery;
var haremHead = (function() {
    var haremType = ($('body#hh_gay').length > 0) ? 'gh1' : 'hh2';
    return 'https://' + haremType;
})();
var CurrentPage = window.location.pathname;
var sheet = (function() {
	var style = document.createElement('style');
	document.head.appendChild(style);
	return style.sheet;
})();

$(document).ready(function() {
    //include lightbox css
    $(document.head).append(
        '<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.css" rel="stylesheet" type="text/css">'
    );
    //define own css
    defineCss();
});

// current page: Activities (PoP)
if (CurrentPage.indexOf('activities') != -1)
{
    if ($('.pop_list').css('display') != 'none') return;

    setTimeout(async function () {
        var popElement = $('#activities #pop.canvas');
        var popImage = popElement.find('.pop_left_part img');
        var popRewardInfo = popElement.find('.pop_rewards_display.reward_wrap').attr('data-reward-display');
        var popImageIcon = popElement.find('.pop_rewards_display .shards_girl_ico img');
        //if girl is won, there is no shards data in popRewardInfo, and therefore no id. Use regex to get girl id from image link?
        var girlInfo = JSON.parse(popRewardInfo).shards[0];
        var girlId = girlInfo.id_girl;

        //check for image existance with high grades (no way to check max grades outside harem so far)
        var girlGrades = 5;
        var checkImageLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ava5.png';
        if (await checkUrlResponse(checkImageLink) === false) girlGrades = 3;

        //create diamonds on the top part
        popElement.find('.diamond-bar').remove();
        var allDiamonds = '';
        for (var i = 0; i <= girlGrades; i++) {
            var diamondToAdd = '<div class="diamond unlocked" grade="' + i + '"></div>';
            allDiamonds += diamondToAdd;
        }
        popImage.before('<div class="diamond-bar-container"><div class="diamond-bar">' + allDiamonds + '</div></div>');

        //connect diamonds to image links
        var allLinks = popElement.find('.diamond');
        var linksArray = [];
        for (i = 0; i <= girlGrades; i++) {
            var imgLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ava' + i + '.png';
            var icoLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ico' + i + '.png';
            linksArray.push(imgLink);
            $(allLinks.get(i)).attr("link", imgLink);
            $(allLinks.get(i)).attr("icoLink", icoLink);
        }

        $( ".pop_left_part .diamond-bar .diamond" ).on('mouseenter', function() {
            var girlAvatarLink = $(this).attr('link');
            var girlIconLink = $(this).attr('icoLink');
            popImage.attr('src', girlAvatarLink);
            popImageIcon.attr('src', girlIconLink);
        });

        //create zooming event
        $(popImage).removeData('allImages');
        $(popImage).data('allImages', linksArray);
        $(popImage).on('mouseup', zoomIntoImage);
    }, 50);
}

// current page: Home
if (CurrentPage.indexOf('home') != -1)
{
    var eventGirlElementSelector = ".event-widget .widget .rewards-block-tape .girl_reward";

    //update view of girl currently selected when loading event info box
    $( ".event-thumbnail" ).on('click', function() {
        setTimeout(function () {
            $(eventGirlElementSelector + "[active_view]").click();
        }, 50);
    });

    $(eventGirlElementSelector).on('click', async function() {
        var girlId = $(this).attr('girl');
        var girlImageDiv = $( ".event-widget.special-fullscreen-view .widget .rewards-stats .reward" );
        var girlImage = girlImageDiv.children('img');
        var girlGrades = 5;
        girlImageDiv.find('.diamond-bar').remove();

        //check for image existance with high grades (no way to check max grades outside harem so far)
        var checkImageLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ava5.png';
        if (await checkUrlResponse(checkImageLink) === false) girlGrades = 3;

        //create diamonds on the top part
        var allDiamonds = '';
        for (var i = 0; i <= girlGrades; i++) {
            var diamondToAdd = '<div class="diamond unlocked" grade="' + i + '"></div>';
            allDiamonds += diamondToAdd;
        }
        girlImage.before('<div class="diamond-bar">' + allDiamonds + '</div>');

        //connect diamonds to image links
        var allLinks = girlImageDiv.find('.diamond');
        var linksArray = [];
        for (i = 0; i <= girlGrades; i++) {
            var imgLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ava' + i + '.png';
            var icoLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ico' + i + '.png';
            linksArray.push(imgLink);
            $(allLinks.get(i)).attr("link", imgLink);
            $(allLinks.get(i)).attr("icoLink", icoLink);
        }

        $( ".rewards-stats .diamond-bar .diamond" ).on('mouseenter', function() {
            var girlAvatarLink = $(this).attr('link');
            var girlIconLink = $(this).attr('icoLink');
            girlImage.attr('src', girlAvatarLink);
        });

        //create zooming event
        $(girlImage).removeData('allImages');
        $(girlImage).data('allImages', linksArray);
        $(girlImage).off('mouseup', zoomIntoImage);
        $(girlImage).on('mouseup', zoomIntoImage);
    });
}

// current page: Harem
if (CurrentPage.indexOf('harem') != -1)
{
    var haremRight = $('#harem_right');

    $( ".girls_list div[id_girl]" ).on('click', function() {
        var girlId = $(this).children('[girl]').attr('girl');
        var girlGrades = $(this).find('.graded').children().length;
        var girlClass = $(this).find('.icon').attr('carac');
        updateInfo(girlId, girlGrades, girlClass);
    });

    //update view of girl currently selected when loading the harem
    setTimeout(function () {
        $("#harem_left div.girls_list div[girl].opened").click();
    }, 100);

    function updateInfo(girlId, girlGrades, girlClass)
    {
        setTimeout(function () {
            haremRight.children('[girl]').each( function() {
                if (girlId == 0) girlId = $(this).attr('girl');

                var girl = girlsDataList[girlId];
                var girlImageDiv = $(this).find('.avatar-box');
                var girlIconDiv = $("#harem_left div.girls_list div[girl].opened div.left img");
                if (girlGrades == 0) girlGrades = girl.nb_grades;

                if (!girl.own) {
                    //create diamonds on the bottom part
                    var allDiamonds = '';
                    for (var i = 0; i <= girlGrades; i++) {
                        var diamondToAdd = '<div class="diamond locked" grade="' + i + '"></div>';
                        allDiamonds += diamondToAdd;
                    }

                    $(this).find('.middle_part').css('margin', '0');
                    $(this).find('.dialog-box').after('<h3>' + girl.Name + '<span carac="class' + girlClass + '"></span></h3>');
                    $(this).find('img.avatar').wrap('<div class="avatar-box"></div>');
                    $(this).find('.avatar-box').css('margin-top', '23px');
                    $(this).find('.avatar-box').after('<div class="diamond-bar">' + allDiamonds + '</div>');
                }

                //update for any girl (owned or not)
                $(this).find('h3').wrap('<div class="WikiLink"></div>').wrap('<a href="https://harem-battle.club/wiki/Harem-Heroes/HH:' + girl.Name + '" target="_blank"></a>');
                var allLinks = $(this).find('.diamond');
                var linksArray = [];
                for (i = 0; i <= girlGrades; i++) {
                    var imgLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ava' + i + '.png';
                    var icoLink = haremHead + '.hh-content.com/pictures/girls/' + girlId + '/ico' + i + '.png';
                    linksArray.push(imgLink);
                    $(allLinks.get(i)).attr("link", imgLink);
                    $(allLinks.get(i)).attr("icoLink", icoLink);
                }
                $('.avatar-box img.avatar').removeData('allImages');
                $('.avatar-box img.avatar').data('allImages', linksArray);
                if (!girl.own) $('.avatar-box img.avatar').attr('src', linksArray[0]);

                $('.variation_block .big_border').on('click', function() {
                    var girlId = $(this).children('[girl]').attr('girl');
                    var girlGrades = $(this).find('.graded').children().length;
                    setTimeout(function() {
                        var girlClass = $(".girls_list div[id_girl] div[girl].opened").find('.icon').attr('carac');
                        updateInfo(girlId, girlGrades, girlClass);
                    }, 50);
                });

                $( ".diamond-bar .diamond" ).on('mouseenter', function() {
                    var mainParent = $(this).closest('.middle_part');
                    var girlAvatar = mainParent.find('img.avatar');
                    var girlAvatarLink = $(this).attr('link');
                    var girlIconLink = $(this).attr('icoLink');
                    girlIconDiv.attr('src', girlIconLink);
                    girlAvatar.attr('src', girlAvatarLink);
                });

                $('.avatar-box img.avatar').on('mouseup', zoomIntoImage);
            });
        }, 0);
    }
}

//zoom into image with lightbox, event only on left click
function zoomIntoImage(e)
{
    if (e.which != 1) return;

    var linksArray = $(this).data('allImages');
    var girlAvatarLink = $(this).attr('src');
    var indexOfQuestion = girlAvatarLink.lastIndexOf('?');
    if (indexOfQuestion >= 0) girlAvatarLink = girlAvatarLink.slice(0, indexOfQuestion);
    var indexOfCurrent = linksArray.indexOf(girlAvatarLink);

    var allImages = [];
    for (var i = 0; i < linksArray.length; i++) {
        allImages.push({
            src  : linksArray[i].toString(),
            type : 'image',
            opts : {
                caption : i == 0 ? 'Default' : 'Stage ' + i
            }
        });
    }

    $.fancybox.open(allImages, {
        loop : true,
        keyboard: true,
        transitionEffect: "tube"
    }, indexOfCurrent);
}

//checks for any errors in url (like image 404)
async function checkUrlResponse(url)
{
    let result = false;

    await fetch(url.toString())
    .then(function(response) {
        if (response.status >= 200 && response.status <= 299) {
            return response;
        } else {
            throw Error(response.statusText);
        }
    }).then(function(response) {
        result = true;
    }).catch(function(error) {
    });

    return result;
}

function defineCss()
{
    sheet.insertRule('#harem_right .WikiLink a {'
                     + 'text-decoration: none; }');

    sheet.insertRule('#harem_right .diamond-bar {'
                     + 'margin-top: 4px; }');

    sheet.insertRule('.rewards-stats .diamond-bar {'
                     + 'position: static;'
                     + 'justify-content: center;'
                     + 'margin-top: 42px;'
                     + 'margin-bottom: -40px; }');

    sheet.insertRule('.rewards-stats .avatars-drawn-bottom-part .diamond-bar {'
                     + 'margin-top: 275px; }');

    sheet.insertRule('.rewards-stats .avatars-drawn-bottom-part img {'
                     + 'margin-top: -275px; }');

    sheet.insertRule('.rewards-stats .diamond-bar .diamond.unlocked, .pop_left_part .diamond-bar .diamond.unlocked {'
                     + 'cursor: default; }');

    sheet.insertRule('.pop_left_part .diamond-bar-container {'
                     + 'z-index: 5;'
                     + 'position: absolute; }');

    sheet.insertRule('.pop_left_part .diamond-bar {'
                     + 'position: relative;'
                     + 'left: 50%; }');

    sheet.insertRule('#harem_right .diamond-bar .diamond:hover, .rewards-stats .diamond-bar .diamond:hover, .pop_left_part .diamond-bar .diamond:hover {'
                     + 'border: 2px solid #FE00FE; }');

    sheet.insertRule('.avatar-box img, .event-widget.special-fullscreen-view .widget .rewards-stats .reward img {'
                     + 'cursor: zoom-in; }');

    sheet.insertRule('#pop.canvas .pop_left_part img.pop_left_fade_page {'
                     + 'margin-bottom: 10px;'
                     + 'cursor: zoom-in; }');
}