HLTB in Backloggd Lists

HLTB times in Backloggd

  1. // ==UserScript==
  2. // @name HLTB in Backloggd Lists
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.1
  5. // @description HLTB times in Backloggd
  6. // @author Siev
  7. // @license MIT
  8. // @match *://www.backloggd.com/*
  9. // @match *://backloggd.com/*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=backloggd.com
  11. // @grant GM_xmlhttpRequest
  12. // ==/UserScript==
  13.  
  14. // TODO: fix the sorting in lists to be across pages
  15.  
  16. let hltbUrl = "https://howlongtobeat.com/api/search/";
  17.  
  18. function sortList() {
  19. let getNodeTime = node => $(node).data('hltbTime');
  20. let sortFunc = $("#sort-direction-btn > .fad").hasClass('fa-sort-down') ?
  21. (a,b) => getNodeTime(b) - getNodeTime(a)
  22. : (a,b) => getNodeTime(a) - getNodeTime(b);
  23. let arr = $('.toggle-fade').children().toArray().toSorted(sortFunc);
  24. $('.toggle-fade').append($(arr));
  25. }
  26.  
  27. // add the options for sorting the list by time
  28. $('[id=nav-interactables]').eq(1)
  29. .find('li.nav-item').last()
  30. .after(function() { return $(this).clone() })
  31. .next()
  32. .click(function () {
  33. $("#sort-direction-btn")
  34. .click(function () {
  35. $('i', this).toggleClass(['fa-sort-up', 'fa-sort-down']);
  36. sortList();
  37. })
  38. .attr('href','javascript: void(0);');
  39. $(this).parent().prev().contents().first()[0].data = ' HLTB Time ';
  40. sortList();
  41. })
  42. .find('a')
  43. .text('HLTB Time')
  44. .attr('href','javascript: void(0);');
  45.  
  46.  
  47. // get time from HLTB
  48. function lookupGame(gameName, context, callback) {
  49. let hltbQuery = '{"searchType":"games","searchTerms":["'+gameName+'"],"size":100}';
  50. GM_xmlhttpRequest({
  51. context: context,
  52. method: "POST",
  53. url: hltbUrl,
  54. data: hltbQuery,
  55. headers: {
  56. "Content-Type": "application/json",
  57. "origin": "https://howlongtobeat.com",
  58. "referer": "https://howlongtobeat.com"
  59. },
  60. onload: function (response) {
  61. var rawTime;
  62. var hltbTime;
  63. let game = response.context;
  64. // Grab response
  65. let hltb = JSON.parse(response.responseText);
  66.  
  67. //Determine if data is present in response by checking the page count. If no data, set default HLTB button.
  68. let hltbPages = hltb['pageTotal'];
  69. if(hltbPages == 0) {
  70. hltbTime = "?";
  71. } else {
  72. let hltbstring = JSON.stringify(hltb);
  73.  
  74. //Make sure you have the right game_name (if possible, otherwise just use first result from response)
  75. let n = 0;
  76. let loop = hltb['count'];
  77. for (let i = 0; i < loop; i++) {
  78. let hltbName = hltb['data'][i]['game_name'];
  79. if (hltbName.toLowerCase() == gameName.toLowerCase()) {
  80. n = i;
  81. break;
  82. }
  83. }
  84.  
  85. // convert and format time
  86. rawTime = hltb['data'][n]['comp_plus'];
  87. hltbTime = rawTime;
  88. hltbTime = hltbTime/60/60; // Convert to hours
  89. hltbTime = Math.round(hltbTime*2)/2; // Round to closes .5
  90. hltbTime = hltbTime.toString().replace(".5","½"); // Convert .5 to ½ to be consistent with HLTB
  91. if (hltbTime[0] == '0') hltbTime = hltbTime.substr(1);
  92. }
  93.  
  94. callback(rawTime, hltbTime, response.context);
  95. }
  96. });
  97. }
  98.  
  99. // showing the time under game cards
  100. $('.card').not('.overlay-hide').filter(function (i) {
  101. return !$(this).parent().parent().next().hasClass('coming-details')
  102. }).each(function (i, game) {
  103. let gameName = $('img', this).attr('alt');
  104. lookupGame(gameName, game, function (raw, fmt, game) {
  105. //$(game).parent().parent().parent().data('hltbTime', raw);
  106. $(game).parents('.toggle-fade > div').data('hltbTime', raw);
  107. $(game).after("<div>" + fmt + " Hours</div>").next().css({ fontSize: '0.9rem', paddingLeft: '0.15rem' });
  108. })
  109. });
  110.  
  111. // showing the time in the game page
  112. let gameName = $("#title > div.col-12.pr-0 > div > div > h1").text();
  113. lookupGame(gameName, 0, function (raw, fmt, context) {
  114. // clone the average score panel and change it to hltb time
  115. var panel = $('.side-section').eq(1).children().first().before(function(i) { return $(this).clone() }).prev();
  116. panel.find('p').text('HLTB Time');
  117. panel.find('h1').text(fmt);
  118. });