您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Beta Version
// ==UserScript== // @name Destiny Emblem Vault // @namespace https://d2ev.hitokagemya.com/ // @version 0.1 // @description Beta Version // @author Hitokage // @match https://www.bungie.net/* // @match https://d2ev.hitokagemya.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bungie.net // @grant GM.cookie // @grant GM_openInTab // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_xmlhttpRequest // @require https://unpkg.com/[email protected]/dist/jquery.min.js // @require https://unpkg.com/[email protected]/dist/sweetalert2.js // @run-at document-end // @license GPL-3.0 // ==/UserScript== let toast = Swal.mixin({ toast: true, position: 'top', showConfirmButton: false, timer: 2000, timerProgressBar: false, didOpen: (toast) => { toast.addEventListener('mouseenter', Swal.stopTimer); toast.addEventListener('mouseleave', Swal.resumeTimer); } }); const message = { success: (text) => { toast.fire({title: text, icon: 'success'}); }, error: (text) => { toast.fire({title: text, icon: 'error'}); }, warning: (text) => { toast.fire({title: text, icon: 'warning'}); }, info: (text) => { toast.fire({title: text, icon: 'info'}); }, question: (text) => { toast.fire({title: text, icon: 'question'}); } }; function sleep (time) { return new Promise((resolve) => setTimeout(resolve, time)); } function jumpToBungie() { GM_openInTab("https://www.bungie.net/7/en/Codes/Redeem", { active: true, setParent: true, insert: true }); } async function getCookie() { let bungleatk; let bungled; bungleatk = await GM.cookie.list({ name: "bungleatk"}); bungled = await GM.cookie.list({ name: "bungled"}); if (bungleatk.length) {bungleatk = bungleatk[0].value} else {bungleatk = null}; if (bungled.length) {bungled = bungled[0].value} else {bungled = null}; return { "bungleatk": bungleatk, "bungled": bungled } } async function getUserUniqueName(cookie) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: "https://www.bungie.net/Platform/User/GetBungieNetUser/?lc=zh-cht&fmt=true&lcin=true", anonymous: true, headers: { 'X-API-KEY': '10E792629C2A47E19356B8A79EEFA640', 'X-CSRF': cookie["bungled"], 'Content-Type': 'text/plain', 'Origin': 'https://www.bungie.net', "Cookie": "bungled=" + cookie["bungled"] + "; bungleatk=" + cookie["bungleatk"], }, onload: function(response) { resolve(JSON.parse(response.responseText).Response.user.uniqueName); }, onerror: function(error) { reject(error); } }); }); } function sendRedeempetionRequest(cookie) { var data = { "hash": GM_getValue("d2ev_hash"), "password": GM_getValue("d2ev_password"), "user": { "bungleatk": cookie["bungleatk"], "bungled": cookie["bungled"], } } return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: "https://d2ev.hitokagemya.com/api/vault/emblem/redeem", anonymous: true, headers: { "Content-Type": "application/json" }, data: JSON.stringify(data), onload: function(response) { const resp = JSON.parse(response.responseText); Swal.fire({ title: "Redeem Result", html: "Item name: " + resp["data"]["emblem_info"] + "<br/>Message: " + resp["data"]["message"] }); resolve(resp); }, onerror: function(error) { reject(error); } }); }); } async function submitRedeempetion(cookie) { const uniqueName = await getUserUniqueName(cookie); Swal.fire({ title: 'Do you want submit code redeempetion request now?', html: 'Please confirm current username:<br/>' + uniqueName, showDenyButton: true, showCancelButton: true, confirmButtonText: 'Yes', denyButtonText: 'No', }).then((result) => { if (result.isConfirmed) { Swal.fire({title: "Please wait", text: "Redeempetion request has been submitted"}, '', 'success') GM_setValue("d2ev_wait_use", false); sendRedeempetionRequest(cookie); } else if (result.isDenied) { Swal.fire('Redeempetion request has been cancelled', '', 'info') GM_setValue("d2ev_wait_use", false); } }) } const checkCurrentUrl = async function () { let currentUrl = window.location.href; var urlRedeemPattern = /^((https|http)?:\/\/)d2ev.hitokagemya.com\/vault\/redeem/; var urlBungiePattern = /^((https|http)?:\/\/)www.bungie.net/; var urlHomePage = /^((https|http)?:\/\/)d2ev.hitokagemya.com\/vault/; if (urlRedeemPattern.test(currentUrl)) { document.getElementById("tips").remove(); GM_setValue("d2ev_wait_use", false); var hashPattern = /hash=(\w{32})/; var pwPattern = /password=(\w{0,99})/; var hash = hashPattern.exec(currentUrl); var password = pwPattern.exec(currentUrl); if (password) {password = password[1]} else {password = ""}; GM_setValue("d2ev_password", password); if (hash) { GM_setValue("d2ev_wait_use", true); GM_setValue("d2ev_hash", hash[1]); jumpToBungie(); } else { message.error("Parse hash failed, please check and retry"); sleep(2000).then(() => { showInput(); }); } } else if (urlBungiePattern.test(currentUrl) && GM_getValue("d2ev_wait_use")) { var cookie = await getCookie(); if (!cookie["bungleatk"] || !cookie["bungled"]) { Swal.fire('After sign in please refresh page to continue auto redeem progress'); } else { submitRedeempetion(cookie); } } else if (urlHomePage.test(currentUrl)) { document.getElementById("tips").remove(); showInput(); } } function showInput() { let dom = '', btn = ''; dom += `<label class="pl-setting-label"><div class="pl-label">Hash</div><input type="text" placeholder="" class="pl-input listener-hash" value="${GM_getValue('d2ev_hash')}"></label>`; dom += `<label class="pl-setting-label"><div class="pl-label">Password</div><input type="text" placeholder="Optional" class="pl-input listener-password" value="${GM_getValue('d2ev_password')}"></label>`; dom = '<div>' + dom + '</div>'; Swal.fire({ title: 'Redeem Emblem', html: dom, icon: 'info', showCloseButton: false, showConfirmButton: true, }).then((result) => { if (result.isConfirmed) { message.success('Got it!'); window.location.replace("https://d2ev.hitokagemya.com/vault/redeem?hash=" + GM_getValue('d2ev_hash') + "&password=" + GM_getValue('d2ev_password')) } }); $(document).on('input', '.listener-hash', async (e) => { GM_setValue('d2ev_hash', e.target.value); }); $(document).on('input', '.listener-password', async (e) => { GM_setValue('d2ev_password', e.target.value); }); } checkCurrentUrl();