[E/Ex-Hentai] AutoLogin

設置 E/Ex - Cookies 本地備份保存 , 自動擷取設置 , 手動選單設置 , 自動檢測登入狀態自動登入 , 手動選單登入

Fra og med 04.08.2023. Se den nyeste version.

  1. // ==UserScript==
  2. // @name [E/Ex-Hentai] AutoLogin
  3. // @name:zh-TW [E/Ex-Hentai] 自動登入
  4. // @name:zh-CN [E/Ex-Hentai] 自动登入
  5. // @name:ja [E/Ex-Hentai] 自動ログイン
  6. // @name:ko [E/Ex-Hentai] 자동 로그인
  7. // @name:en [E/Ex-Hentai] AutoLogin
  8. // @version 0.0.12
  9. // @author HentiSaru
  10. // @description 設置 E/Ex - Cookies 本地備份保存 , 自動擷取設置 , 手動選單設置 , 自動檢測登入狀態自動登入 , 手動選單登入
  11. // @description:zh-TW 設置 E/Ex - Cookies 本地備份保存 , 自動擷取設置 , 手動選單設置 , 自動檢測登入狀態自動登入 , 手動選單登入
  12. // @description:zh-CN 设置 E/Ex - Cookies 本地备份保存 , 自动撷取设置 , 手动选单设置 , 自动检测登入状态自动登入 , 手动选单登入
  13. // @description:ja E/Ex - Cookies をローカルバックアップ保存し、自動的に設定し、手動でメニューを設定し、ログイン狀態を自動的に検出して自動ログインし、手動でメニューログインします
  14. // @description:ko E/Ex - 쿠키를 로컬 백업으로 저장하고 자동으로 설정하며 수동으로 메뉴를 설정하고 로그인 상태를 자동으로 감지하여 자동으로 로그인하거나 메뉴로 수동으로 로그인합니다
  15. // @description:en Save E/Ex cookies as local backups, automatically retrieve settings, manually configure the menu, automatically detect login status for auto-login, and allow manual login through the menu
  16.  
  17. // @match https://e-hentai.org/*
  18. // @match https://exhentai.org/*
  19. // @icon https://e-hentai.org/favicon.ico
  20.  
  21. // @license MIT
  22. // @namespace https://greasyfork.org/users/989635
  23.  
  24. // @run-at document-end
  25. // @grant GM_addStyle
  26. // @grant GM_setValue
  27. // @grant GM_getValue
  28. // @grant GM_notification
  29. // @grant GM_registerMenuCommand
  30. // ==/UserScript==
  31.  
  32. /* ==================== 初始化設置 ==================== */
  33. var modal, Domain;
  34.  
  35. (function() {
  36. try {
  37. let cookies = GM_getValue("E/Ex_Cookies", []), domain = window.location.hostname,
  38. sessiontime = new Date(GM_getValue(`${domain}_SessionTime`, null)), time = new Date(), conversion;
  39. if (isNaN(sessiontime)) {sessiontime = new Date(time.getTime() + 6 * 60 * 1000)}
  40. conversion = (time - sessiontime) / (1000 * 60);
  41. if (conversion > 5) {
  42. GM_setValue(`${domain}_SessionTime`, time.getTime());
  43. AutomaticLoginCheck(JSON.parse(cookies), domain);
  44. }
  45. } catch (error) {console.log(error)}
  46. })();
  47.  
  48. GM_addStyle(`
  49. .show-modal-background {
  50. top: 0;
  51. left: 0;
  52. width: 100%;
  53. height: 100%;
  54. z-index: 9999;
  55. position: fixed;
  56. overflow: auto;
  57. background-color: rgba(0,0,0,0.5);
  58. }
  59. .show-modal-content {
  60. width: 23%;
  61. padding: 20px;
  62. overflow: auto;
  63. color: #5C0D11;
  64. margin: 5% auto;
  65. text-align: left;
  66. border-radius: 10px;
  67. border-collapse: collapse;
  68. background-color: #fefefe;
  69. border: 2px ridge #5C0D12;
  70. }
  71. .show-button {
  72. top: 0;
  73. margin: 3% 2%;
  74. color: #5C0D12;
  75. font-size: 14px;
  76. font-weight: bold;
  77. border-radius: 3px;
  78. background-color: #EDEADA;
  79. border: 2px solid #B5A4A4;
  80. }
  81. .show-button:hover, .show-button:focus {
  82. color: #FF8033;
  83. cursor: pointer;
  84. text-decoration: none;
  85. }
  86. .set-modal-content {
  87. width: 720px;
  88. padding: 5px;
  89. overflow: auto;
  90. border-radius: 10px;
  91. text-align: center;
  92. border: 2px ridge #5C0D12;
  93. border-collapse: collapse;
  94. margin: 2% auto 8px auto;
  95. }
  96. .set-list {
  97. height: 25px;
  98. width: 70%;
  99. text-align: center;
  100. }
  101. .hidden {
  102. display: none;
  103. }
  104. `);
  105.  
  106. /* 自動獲取 Cookies */
  107. const GetCookiesAutomatically = GM_registerMenuCommand(
  108. "📜 自動獲取 Cookies [請先登入]",
  109. function() {
  110. let cookies = GetCookies() , cookie_list = [];
  111. for (var cookieName in cookies) {
  112. if (cookies.hasOwnProperty(cookieName)) {
  113. var cookieValue = cookies[cookieName];
  114. cookie_list.push({"name" : cookieName,"value" : cookieValue})
  115. }
  116. }
  117. cookies = JSON.stringify(cookie_list, null, 4);
  118. Cookies_Show(cookies)
  119. }
  120. )
  121.  
  122. /* 顯示自動獲取的 Cookies */
  123. function Cookies_Show(cookie_list) {
  124. if (modal) {
  125. modal.remove();
  126. modal = null;
  127. }
  128. modal = document.createElement('div');
  129. modal.innerHTML = `
  130. <div class="show-modal-content">
  131. <h1 style="text-align:center;">確認選擇的 Cookies</h1>
  132. <pre><b>${cookie_list}</b></pre>
  133. <div style="text-align: right;">
  134. <button class="show-button" id="save_cookie">確認保存</button>
  135. <button class="show-button" id="modal_close">取消退出</button>
  136. </div>
  137. </div>
  138. `
  139. modal.classList.add('show-modal-background');
  140. document.body.appendChild(modal);
  141. modal.classList.remove('hidden');
  142.  
  143. let CloseButton = document.getElementById('modal_close');
  144. CloseButton.addEventListener('click', () => {
  145. modal.classList.add('hidden');
  146. document.removeEventListener('click', CloseButton);
  147. });
  148. let SaveButton = document.getElementById('save_cookie');
  149. SaveButton.addEventListener('click', () => {
  150. GM_setValue("E/Ex_Cookies", cookie_list);
  151. alert("保存成功!");
  152. modal.classList.add('hidden');
  153. document.removeEventListener('click', SaveButton);
  154. });
  155. }
  156.  
  157. /* 手動輸入 Cookies */
  158. const ManualSetting = GM_registerMenuCommand(
  159. "📝 手動輸入 Cookies",
  160. function() {
  161. if (modal) {
  162. modal.remove();
  163. modal = null;
  164. }
  165.  
  166. Domain = window.location.hostname;
  167. if (Domain === "e-hentai.org") {
  168. GM_addStyle('.set-modal-content { background-color: #fefefe; }');
  169. } else if (Domain === "exhentai.org") {
  170. GM_addStyle('.set-modal-content { background-color: #34353b; }');
  171. }
  172.  
  173. modal = document.createElement('div');
  174. modal.innerHTML = `
  175. <div class="set-modal-content">
  176. <h1>設置 Cookies</h1>
  177. <form id="set_cookies">
  178. <div style="margin:10px">
  179. [igneous] : <input class="set-list" type="text" name="igneous" placeholder="要登入 Ex 才需要填寫"><br>
  180. [ipb_member_id] : <input class="set-list" type="text" name="ipb_member_id" placeholder="必填項目" required><br>
  181. [ipb_pass_hash] : <input class="set-list" type="text" name="ipb_pass_hash" placeholder="必填項目" required><hr>
  182. <h2>下方選填 也可不修改</h2>
  183. [sl] : <input class="set-list" type="text" name="sl" value="dm_2"><br>
  184. [sk] : <input class="set-list" type="text" name="sk" value="gy8wgij076agx1ax6is9htzrj40i"><br>
  185. [yay] : <input class="set-list" type="text" name="yay" value="louder"><br>
  186. </div>
  187. <button type="submit" class="show-button" id="set_save_cookie">確認保存</button>
  188. <button class="show-button" id="set_modal_close">退出選單</button>
  189. </form>
  190. </div>
  191. `
  192.  
  193. modal.classList.add('show-modal-background');
  194. document.body.appendChild(modal);
  195. modal.classList.remove('hidden');
  196. const textarea = document.createElement("textarea");
  197.  
  198. // 退出按鈕
  199. let CloseButton = document.getElementById("set_modal_close");
  200. CloseButton.addEventListener("click", () => {
  201. modal.classList.add("hidden");
  202. document.removeEventListener("click", CloseButton);
  203. });
  204.  
  205. // 捕獲表單提交事件
  206. document.getElementById("set_cookies").addEventListener("submit", function(event) {
  207. event.preventDefault(); // 阻止默認的表單提交行為
  208. if (event.submitter.id === "set_save_cookie") {
  209. // 獲取所有的輸入表單
  210. const formElements = document.querySelectorAll("#set_cookies .set-list");
  211. const cookie_list = Array.from(formElements).map(input => {
  212. return { name: input.name, value: input.value };
  213. });
  214.  
  215. textarea.name = "confirm_cookies";
  216. textarea.style = "margin-top:20px";
  217. textarea.rows = 20;
  218. textarea.cols = 60;
  219.  
  220. // 保存後 , 在獲取並轉換格式 , 並將其顯示
  221. GM_setValue("E/Ex_Cookies", JSON.stringify(cookie_list, null, 4));
  222. let cookies = JSON.parse(GM_getValue("E/Ex_Cookies", []));
  223. textarea.value = JSON.stringify(cookies , null, 4);
  224.  
  225. // 將 textarea 添加到指定的 div 元素中
  226. const formDiv = document.querySelector("#set_cookies div");
  227. formDiv.appendChild(textarea);
  228.  
  229. GM_notification({
  230. title: "保存通知",
  231. text: "[確認輸入正確]按下退出選單保存",
  232. image: "https://cdn-icons-png.flaticon.com/512/5234/5234222.png",
  233. timeout: 4000
  234. });
  235. }
  236. });
  237. }
  238. )
  239.  
  240. /* 查看保存的 Cookies */
  241. const ViewSaveCookie = GM_registerMenuCommand(
  242. "🔍 查看保存的 Cookies",
  243. function() {
  244. if (modal) {
  245. modal.remove();
  246. modal = null;
  247. }
  248.  
  249. Domain = window.location.hostname;
  250. if (Domain === "e-hentai.org") {
  251. GM_addStyle('.set-modal-content { background-color: #fefefe; }');
  252. } else if (Domain === "exhentai.org") {
  253. GM_addStyle('.set-modal-content { background-color: #34353b; }');
  254. }
  255.  
  256. modal = document.createElement('div');
  257. modal.innerHTML = `
  258. <div class="set-modal-content">
  259. <h1>當前設置 Cookies</h1>
  260. <div id="view_cookies" style="margin:10px"></div>
  261. <button class="show-button" id="save_changes">更改保存</button>
  262. <button class="show-button" id="close">退出選單</button>
  263. </div>
  264. `
  265.  
  266. modal.classList.add('show-modal-background');
  267. document.body.appendChild(modal);
  268. modal.classList.remove('hidden');
  269.  
  270. let CloseButton = document.getElementById("close");
  271. CloseButton.addEventListener("click", () => {
  272. modal.classList.add("hidden");
  273. document.removeEventListener("click", CloseButton);
  274. });
  275.  
  276. const textarea = document.createElement("textarea");
  277. const login_cookies = JSON.parse(GM_getValue("E/Ex_Cookies", []));
  278. textarea.value = JSON.stringify(login_cookies , null, 4);
  279.  
  280. textarea.id = "view_SC";
  281. textarea.style = "margin-top:20px";
  282. textarea.rows = 20;
  283. textarea.cols = 60;
  284. document.getElementById("view_cookies").appendChild(textarea);
  285.  
  286. let SaveButton = document.getElementById("save_changes");
  287. SaveButton.addEventListener("click", () => {
  288. GM_setValue("E/Ex_Cookies", JSON.stringify(JSON.parse(document.getElementById("view_SC").value), null, 4));
  289. GM_notification({
  290. title: "變更通知",
  291. text: "以保存變更",
  292. image: "https://cdn-icons-png.flaticon.com/512/5234/5234222.png",
  293. timeout: 4000
  294. });
  295. modal.classList.add("hidden");
  296. document.removeEventListener("click", SaveButton);
  297. });
  298. }
  299. )
  300.  
  301. /* 手動注入 Cookies 登入 */
  302. const CookieInjection = GM_registerMenuCommand(
  303. "🔃 手動注入 Cookies",
  304. function() {
  305. try {
  306. let login_cookies = GM_getValue("E/Ex_Cookies", []);
  307. let cookies = GetCookies();
  308. login_cookies = JSON.parse(login_cookies);
  309. DeleteCookies(cookies);
  310. AddCookies(login_cookies);
  311. GM_setValue("SessionTime", new Date().getTime());
  312. location.reload();
  313. } catch (error) {
  314. alert("未檢測到可注入的 Cookies !!\n請從選單中進行設置");
  315. }
  316. }
  317. );
  318.  
  319. /* 刪除所有 Cookies */
  320. const CookieDelete = GM_registerMenuCommand(
  321. "🗑️ 刪除所有 Cookies",
  322. function() {
  323. DeleteCookies(GetCookies());
  324. location.reload();
  325. }
  326. );
  327.  
  328. /* 登入檢測函數 */
  329. async function AutomaticLoginCheck(login_cookies , Domain) {
  330. // 需要的 cookie 值
  331. let RequiredCookies = ["ipb_member_id","ipb_pass_hash"];
  332. if (Domain === "exhentai.org") {
  333. RequiredCookies = ["igneous","ipb_member_id","ipb_pass_hash"];
  334. }
  335. let cookies = GetCookies();
  336. let cookiesFound = RequiredCookies.every(function(cookieName) {
  337. return cookies.hasOwnProperty(cookieName) && cookies[cookieName] !== undefined;
  338. });
  339. if (Domain === "exhentai.org" && (!cookies.hasOwnProperty("igneous") || cookies.igneous === "mystery") || !cookiesFound) {
  340. DeleteCookies(cookies);
  341. AddCookies(login_cookies);
  342. location.reload();
  343. } else if (!cookiesFound || !RequiredCookies.length >= 2) {
  344. let cookies = document.cookie.split("; ");
  345. DeleteCookies(cookies);
  346. AddCookies(login_cookies);
  347. location.reload();
  348. }
  349. }
  350.  
  351. /* 添加 cookie */
  352. function AddCookies(LoginCookies) {
  353. for (let i = 0; i < LoginCookies.length; i++) {
  354. let cookie = LoginCookies[i];
  355. document.cookie = cookie.name + "=" + cookie.value;
  356. }
  357. }
  358.  
  359. /* 刪除 cookie */
  360. function DeleteCookies(cookies) {
  361. const cookieNames = Object.keys(cookies);
  362. for (let i = 0; i < cookieNames.length; i++) {
  363. let cookieName = cookieNames[i]; // 為了避免例外狀況沒刪除乾淨
  364. document.cookie = cookieName + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.exhentai.org";
  365. document.cookie = cookieName + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.e-hentai.org";
  366. document.cookie = cookieName + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
  367. }
  368. }
  369.  
  370. /* 取得 Cookies */
  371. function GetCookies() {
  372. let cookies = {} , cookiePairs = document.cookie.split("; ");
  373. for (let i = 0; i < cookiePairs.length; i++) {
  374. let cookiePair = cookiePairs[i].split("=");
  375. let cookieName = decodeURIComponent(cookiePair[0]);
  376. let cookieValue = decodeURIComponent(cookiePair[1]);
  377. cookies[cookieName] = cookieValue;
  378. }
  379. return cookies;
  380. }