F95Zone Search Buttons for DLsite

Adds modern, well-aligned buttons to search for the current game, circle, and product ID on F95Zone, OtomiGames, and RyuuGames. Keeps "Circle: [Name]" on one line and places circle buttons side by side.

  1. // ==UserScript==
  2. // @name F95Zone Search Buttons for DLsite
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.2
  5. // @description Adds modern, well-aligned buttons to search for the current game, circle, and product ID on F95Zone, OtomiGames, and RyuuGames. Keeps "Circle: [Name]" on one line and places circle buttons side by side.
  6. // @author FunkyJustin
  7. // @match https://www.dlsite.com/maniax/work/=/product_id/*
  8. // @match https://www.dlsite.com/pro/work/=/product_id/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Wait for page load
  17. window.addEventListener('load', createSearchButtons);
  18.  
  19. function createSearchButtons() {
  20. // 1. Extract game/circle info
  21. const gameTitleEl = document.querySelector('h1#work_name');
  22. const circleNameEl = document.querySelector('span[itemprop="brand"] a');
  23. if (!gameTitleEl || !circleNameEl) return;
  24.  
  25. const gameTitle = gameTitleEl.innerText.trim();
  26. const circleName = circleNameEl.innerText.trim();
  27.  
  28. let productId = window.location.href.match(/product_id\/([^\/]+)/)[1] || '';
  29. productId = productId.replace('.html', '');
  30.  
  31. // 2. Define URLs
  32. // F95Zone
  33. const f95zoneGameLink = `https://f95zone.to/sam/latest_alpha/#/cat=games/page=1/search=${encodeURIComponent(gameTitle)}`;
  34. const f95zoneForumLink = `https://f95zone.to/search/?q=${encodeURIComponent(gameTitle)}&t=post&c[child_nodes]=1&c[nodes][0]=2&c[title_only]=1&o=relevance`;
  35. const f95zoneCircleLink = `https://f95zone.to/sam/latest_alpha/#/cat=games/page=1/creator=${encodeURIComponent(circleName)}`;
  36. const f95zoneProductIdLink = `https://f95zone.to/search/?q=${encodeURIComponent(productId)}`;
  37.  
  38. // OtomiGames
  39. const otomiGamesSearchLink = `https://otomi-games.com/?s=${encodeURIComponent(gameTitle)}`;
  40. const otomiGamesProductIdLink = `https://otomi-games.com/${productId}/`;
  41.  
  42. // RyuuGames
  43. const ryuuGamesTitleLink = `https://www.ryuugames.com/?s=${encodeURIComponent(gameTitle)}`;
  44. const ryuuGamesProductIdLink = `https://www.ryuugames.com/?s=${encodeURIComponent(productId)}`;
  45. const ryuuGamesCircleLink = `https://www.ryuugames.com/?s=${encodeURIComponent(circleName)}`;
  46.  
  47. // 3. Common button styling
  48. const buttonBaseStyle = {
  49. display: 'inline-block',
  50. padding: '8px 16px',
  51. margin: '5px',
  52. color: '#fff',
  53. backgroundColor: '#009688',
  54. borderRadius: '4px',
  55. textDecoration: 'none',
  56. fontSize: '0.9rem',
  57. cursor: 'pointer',
  58. transition: 'background-color 0.3s ease'
  59. };
  60.  
  61. function createButton(text, url) {
  62. const a = document.createElement('a');
  63. a.innerText = text;
  64. a.href = url;
  65. a.target = '_blank';
  66. Object.assign(a.style, buttonBaseStyle);
  67. // Hover effect
  68. a.addEventListener('mouseover', () => {
  69. a.style.backgroundColor = '#00796B';
  70. });
  71. a.addEventListener('mouseout', () => {
  72. a.style.backgroundColor = '#009688';
  73. });
  74. return a;
  75. }
  76.  
  77. // 4. Create buttons
  78. // Title-based searches
  79. const f95GameBtn = createButton('Search on F95Zone', f95zoneGameLink);
  80. const f95ForumBtn = createButton('Search on F95Zone Forums', f95zoneForumLink);
  81. const f95PIDBtn = createButton('Search Product ID on F95Zone', f95zoneProductIdLink);
  82. const otomiGameBtn = createButton('Search on OtomiGames', otomiGamesSearchLink);
  83. const otomiPIDBtn = createButton('Search Product ID on OtomiGames', otomiGamesProductIdLink);
  84. const ryuuGameBtn = createButton('Search on RyuuGames', ryuuGamesTitleLink);
  85. const ryuuPIDBtn = createButton('Search Product ID on RyuuGames', ryuuGamesProductIdLink);
  86.  
  87. // Circle-based searches
  88. const f95CircleBtn = createButton('Search Circle on F95Zone', f95zoneCircleLink);
  89. const ryuuCircleBtn = createButton('Search Circle on RyuuGames', ryuuGamesCircleLink);
  90.  
  91. // 5. Append Title Buttons in a Flex Container
  92. const titleContainer = document.querySelector('.base_title_br');
  93. if (titleContainer) {
  94. const titleFlex = document.createElement('div');
  95. titleFlex.style.display = 'flex';
  96. titleFlex.style.flexWrap = 'wrap';
  97. titleFlex.style.alignItems = 'center';
  98. titleFlex.style.marginTop = '10px';
  99.  
  100. [f95GameBtn, f95ForumBtn, f95PIDBtn,
  101. otomiGameBtn, otomiPIDBtn,
  102. ryuuGameBtn, ryuuPIDBtn]
  103. .forEach(btn => titleFlex.appendChild(btn));
  104.  
  105. titleContainer.appendChild(titleFlex);
  106. }
  107.  
  108. // 6. Append Circle Buttons Side by Side
  109. // Insert right after the circle name, so "Circle: BLACK PANDA" remains on one line
  110. const circleButtonWrapper = document.createElement('span');
  111. circleButtonWrapper.style.display = 'inline-flex';
  112. circleButtonWrapper.style.flexWrap = 'nowrap';
  113. circleButtonWrapper.style.alignItems = 'center';
  114. circleButtonWrapper.style.marginLeft = '10px';
  115. // Add both buttons side by side
  116. circleButtonWrapper.appendChild(f95CircleBtn);
  117. circleButtonWrapper.appendChild(ryuuCircleBtn);
  118.  
  119. circleNameEl.insertAdjacentElement('afterend', circleButtonWrapper);
  120.  
  121. // 7. Auto-submit on F95Zone forum pages
  122. if (window.location.href === f95zoneForumLink || window.location.href === f95zoneProductIdLink) {
  123. window.onload = function() {
  124. setTimeout(function() {
  125. const searchField = document.querySelector('.input[name="keywords"]');
  126. if (searchField) {
  127. searchField.value = gameTitle;
  128. searchField.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
  129. }
  130. }, 1000);
  131. };
  132. }
  133. }
  134. })();