Kemono跳转

在一些特定网站添加跳转至kemono按钮

  1. // ==UserScript==
  2. // @name Kemono跳转
  3. // @namespace https://github.com/ZIDOUZI/kemono-jump-js
  4. // @version 2.4.12
  5. // @description 在一些特定网站添加跳转至kemono按钮
  6. // @author 子斗子
  7. // @license MIT
  8. // @match https://*.pixiv.net/*
  9. // @match https://*.dlsite.com/*/RG*.html
  10. // @match https://*.fantia.jp/fanclubs/*
  11. // @match https://*.fanbox.cc/*
  12. // @match https://*.patreon.com/user?u=*
  13. // @icon https://kemono.party/static/favicon.ico
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_registerMenuCommand
  17. // @grant GM_unregisterMenuCommand
  18. // ==/UserScript==
  19.  
  20.  
  21.  
  22. (function () {
  23.  
  24. const language = navigator.language || navigator.userLanguage;
  25.  
  26. var openInNew = GM_getValue('OpenInNew', false);
  27.  
  28. let openInNewId = GM_registerMenuCommand(`[${openInNew ? "✔" : "✖"}]新建标签页打开`, openInNew_callback);
  29.  
  30. function openInNew_callback() {
  31. GM_unregisterMenuCommand(openInNewId);
  32. openInNew = !openInNew;
  33. GM_setValue('OpenInNew', openInNew);
  34. openInNewId = GM_registerMenuCommand(`[${openInNew ? "✔" : "✖"}]新建标签页打开`, openInNew_callback);
  35. }
  36.  
  37. var domain = GM_getValue('Domain', 'kemono.party');
  38.  
  39. let domainId = GM_registerMenuCommand(`当前域名:${domain}`, domain_callback);
  40.  
  41. function domain_callback() {
  42. var result = prompt(language === 'zh-CN' ? '请输入域名, 例如kemono.su' : 'Please enter the domain name, for example kemono.su', domain);
  43. if (!result) return;
  44. domain = result;
  45. GM_setValue('Domain', domain);
  46. GM_unregisterMenuCommand(domainId);
  47. domainId = GM_registerMenuCommand(`当前域名:${domain}`, domain_callback);
  48. }
  49.  
  50.  
  51.  
  52. //创建容器
  53. const item = document.createElement('item');
  54. item.id = 'SIR';
  55. item.innerHTML = `
  56. <button class="SIR-button">跳转至Kemono</button>
  57. `;
  58.  
  59. document.body.append(item)
  60.  
  61. //创建样式
  62. const style = document.createElement('style');
  63. style.innerHTML = `
  64. #SIR * {
  65. box-sizing: border-box;
  66. padding: 0;
  67. margin: 0;
  68. }
  69. #SIR .SIR-button {
  70. display: inline-block;
  71. height: 22px;
  72. margin-right: 10px;
  73. opacity: 0.5;
  74. background: white;
  75. font-size: 13px;
  76. padding:0 5px;
  77. position:fixed;
  78. bottom:2px;
  79. right:2px;
  80. border: solid 2px black;
  81. z-index: 9999;
  82. }
  83. `;
  84.  
  85. const button = item.querySelector('.SIR-button')
  86. button.onclick = async () => {
  87. var url = await getKemonoUrl(window.location.href, domain);
  88. if (openInNew) {
  89. window.open(url);
  90. } else {
  91. self.location = url;
  92. }
  93. }
  94.  
  95. document.head.append(style)
  96.  
  97. })();
  98.  
  99. async function getKemonoUrl(url, domain) {
  100.  
  101. function getFanbox(creatorId) {
  102. return new Promise((resolve, reject) => {
  103. fetch(`https://api.fanbox.cc/creator.get?creatorId=${creatorId}`, {
  104. method: "get",
  105. credentials: "include"
  106. })
  107. .then(r => {
  108. if (r.ok) {
  109. return r.json()
  110. } else {
  111. reject({ status: r.status, statusText: r.statusText })
  112. }
  113. })
  114. .then(data => resolve(data))
  115. .catch(e => reject(e))
  116. })
  117. }
  118.  
  119. const pixiv_user = /https:\/\/www\.pixiv\.net\/users\/(\d+)/i;
  120. const pixiv_artworks = /https:\/\/www\.pixiv\.net\/artworks\/(\d+)/i;
  121. const fantia_user = /https:\/\/fantia\.jp\/fanclubs\/(\d+)(\/posts(\S+))?/i;
  122. const fanbox_user1 = /https:\/\/www\.fanbox\.cc\/@([^/]+)(\/posts\/(\d+))?/i;
  123. const fanbox_user2 = /https:\/\/(.+)\.fanbox\.cc(\/posts\/(\d+))?/i;
  124. const dlsite_user = /https:\/\/www.dlsite.com\/.+?\/profile\/=\/maker_id\/(RG\d+).html/i;
  125. const patreon_user1 = /https:\/\/www.patreon.com\/user\?u=(\d+)/i;
  126. const patreon_user2 = /https:\/\/www.patreon.com\/(\w+)/i;
  127.  
  128. let service;
  129. let id;
  130. let post = null;
  131.  
  132. if (pixiv_user.test(url)) {
  133. //pixiv artist
  134. service = "fanbox"
  135. id = url.match(pixiv_user)[1]
  136. } else if (pixiv_artworks.test(url)) {
  137. //pixiv artworks
  138. service = "fanbox";
  139. var artist = document.querySelector("div.sc-f30yhg-2>a.sc-d98f2c-0");
  140. if (artist) {
  141. id = artist.href.match(pixiv_user)[1]
  142. } else {
  143. window.alert("try get artist id failed")
  144. return;
  145. }
  146. } else if (fantia_user.test(url)) {
  147. //fantia
  148. service = "fantia"
  149. id = url.match(fantia_user)[1]
  150. } else if (dlsite_user.test(url)) {
  151. service = "dlsite"
  152. id = url.match(dlsite_user)[1]
  153. } else if (fanbox_user1.test(url) || fanbox_user2.test(url)) {
  154. //fanbox
  155. service = "fanbox"
  156. let matches = fanbox_user1.test(url) ? url.match(fanbox_user1) : url.match(fanbox_user2);
  157. id = (await getFanbox(matches[1])).body.user.userId
  158. post = matches[3]
  159. } else if (patreon_user1.test(url)) {
  160. // patreon
  161. service = "patreon"
  162. id = url.match(patreon_user1)[1]
  163. } else {
  164. window.alert("unknown")
  165. return;
  166. }
  167.  
  168. return `https://${domain}/${service}/user/${id}` + (post == null ? '' : `/post/${post}`)
  169.  
  170. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址