// ==UserScript== // @name 心守_beanfun 动态密码获取插件 // @namespace XinShou // @version 0.1.0 // @description 冒险岛台服香港号快速获取游戏登陆密码网页插件版 // @author 心守 // @match https://bfweb.hk.beanfun.com/game_zone/ // @connect beanfun.com // @require https://cdn.staticfile.org/vue/2.7.14/vue.min.js // @require https://code.jquery.com/jquery-3.5.1.min.js // @require https://gitee.com/nnmy/beanfun-oil-monkey-plugin/raw/master/lib/crypto-js.min.js // @require https://gitee.com/nnmy/beanfun-oil-monkey-plugin/raw/master/lib/bootstrap.bundle.min.js // @resource bootstrapCss https://gitee.com/nnmy/beanfun-oil-monkey-plugin/raw/master/lib/bootstrap.min.css // @grant unsafeWindow // @grant GM_openInTab // @grant GM.openInTab // @grant GM_getValue // @grant GM.getValue // @grant GM_setValue // @grant GM.setValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM.xmlHttpRequest // @grant GM_getResourceText // @grant GM_registerMenuCommand // ==/UserScript== //共有方法,全局共享 function commonFunction() { //获取缓存 this.GMgetValue = function (name, value = null) { let storageValue = value; if (typeof GM_getValue === "function") { storageValue = GM_getValue(name, value); } else if (typeof GM.setValue === "function") { storageValue = GM.getValue(name, value); } else { var arr = window.localStorage.getItem(name); if (arr != null) { storageValue = arr } } return storageValue; }; //设置缓存 this.GMsetValue = function (name, value) { if (typeof GM_setValue === "function") { GM_setValue(name, value); } else if (typeof GM.setValue === "function") { GM.setValue(name, value); } else { window.localStorage.setItem(name, value) } }; //添加css样式 this.GMaddStyle = function (css) { var myStyle = document.createElement('style'); myStyle.textContent = css; var doc = document.head || document.documentElement; doc.appendChild(myStyle); }; //获取随机数 this.randomRange = function (min, max) { return Math.floor(Math.random() * (max - min)) + min; }; this.getCookie = function (name) { var arrstr = document.cookie.split("; "); for (var i = 0; i < arrstr.length; i++) { var temp = arrstr[i].split("="); if (temp[0] == name) { return unescape(temp[1]); } } return null; }; //网络请求 this.request = function (mothed, url, param) { return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ url: url, method: mothed, data: param, onload: function (response) { var status = response.status; if (status == 200 || status == '200') { var responseText = response.responseText; resolve({ "result": "success", "data": responseText }); } else { reject({ "result": "error", "data": null }); } } }); }) }; this.addCommonHtmlCss = function () { var cssText = ` @keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-webkit-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-moz-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-o-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @-ms-keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1} } @keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-webkit-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-moz-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-o-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } @-ms-keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0} } .web-toast-kkli9{ position: fixed; background: rgba(0, 0, 0, 0.7); color: #fff; font-size: 14px; line-height: 1; padding:10px; border-radius: 3px; left: 50%; transform: translateX(-50%); -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); z-index: 999999999999999999999999999; white-space: nowrap; } .fadeOut{ animation: fadeOut .5s; } .fadeIn{ animation:fadeIn .5s; } `; this.GMaddStyle(cssText); }; //小提示框 this.webToast = function (params) { var time = params.time; var background = params.background; var color = params.color; var position = params.position; //center-top, center-bottom var defaultMarginValue = 50; if (time == undefined || time == '') { time = 3000; } var el = document.createElement("div"); el.setAttribute("class", "web-toast-kkli9"); el.innerHTML = params.message; //背景颜色 if (background != undefined && background != '') { el.style.backgroundColor = background; } //字体颜色 if (color != undefined && color != '') { el.style.color = color; } //显示位置 if (position == undefined || position == '') { position = "center-bottom"; } //设置显示位置,当前有种两种形式 if (position === "center-bottom") { el.style.bottom = defaultMarginValue + "px"; } else { el.style.top = defaultMarginValue + "px"; } el.style.zIndex = 999999; document.body.appendChild(el); el.classList.add("fadeIn"); setTimeout(function () { el.classList.remove("fadeIn"); el.classList.add("fadeOut"); /*监听动画结束,移除提示信息元素*/ el.addEventListener("animationend", function () { document.body.removeChild(el); }); el.addEventListener("webkitAnimationEnd", function () { document.body.removeChild(el); }); }, time); }; this.addCommonPopup = function () { let html = `
`; $("body").prepend(html); }; } //全局统一方法对象 const commonFunctionObject = new commonFunction(); const accounts = []; function initWindow() { let startBtn = $(".StartButtonSmall")[0]; if (startBtn == undefined || startBtn == null) return; //打开我的账号列表 startBtn.children[0].click(); } //获取账号信息 async function initAccountInfo() { let url = "https://bfweb.hk.beanfun.com/beanfun_block/game_zone/game_server_account_list.aspx?sc=610074&sr=T9&dt=" + Date.now(); let resultData = await commonFunctionObject.request("get", url, null); if (resultData.result == "success") { let html = resultData.data; if (html.indexOf("請重新登入") !== -1) { //这里需要重新打开一下账号列表 commonFunctionObject.webToast({ message: "获取账号信息失败,为您自动获取账号信息" }); initWindow(); return; } //获取账号信息 let accountList = $(html).find("#ulServiceAccountList")[0]; if (accountList == undefined || accountList == null) return; //有的人有两个账号,所以需要遍历 let len = accountList.children.length; for (var i = 0; i < len; i++) { let item = accountList.children[i]; //存放账号信息的div let accDiv = item.firstChild; if (accDiv == undefined || accDiv == null) continue; let sn = $(accDiv).attr("sn"); let time = await getAccountCreateTime(sn); accounts.push({ title: accDiv.id, name: accDiv.innerText, sn: sn, createTime: time }); } } } async function getAccountPollingKey(sn) { let url = "https://bfweb.hk.beanfun.com/beanfun_block/game_zone/game_start_step2.aspx?service_code=610074&service_region=T9&sotp=" + sn + "&dt=" + Date.now(); let resultData = await commonFunctionObject.request("get", url, null); if (resultData.result == "success") { let str = resultData.data; if (str.length > 0) { let arr = str.match("GetResultByLongPolling&key=(.*?)\""); if (arr.length == 2) { return arr[1]; } } } return ""; } async function getAccountSecret() { let url = "https://login.hk.beanfun.com/generic_handlers/get_cookies.ashx"; let resultData = await commonFunctionObject.request("get", url, null) if (resultData.result == "success") { let str = resultData.data; if (str.length > 0) { let arr = str.match("var\\sm_strSecretCode\\s=\\s'(.*)'"); if (arr.length == 2) { return arr[1]; } } } return ""; } async function getAccountCreateTime(sn) { let url = "https://bfweb.hk.beanfun.com/beanfun_block/game_zone/game_start_step2.aspx?service_code=610074&service_region=T9&sotp=" + sn + "&dt=" + Date.now(); let resultData = await commonFunctionObject.request("get", url, null); if (resultData.result == "success") { let str = resultData.data; if (str.length > 0) { let arr = str.match("ServiceAccountCreateTime:\\s\\\"([^\\\"]+)\\\""); if (arr.length == 2) { return arr[1]; } } } return ""; } async function getDynamicPwd(account) { let url = "https://bfweb.hk.beanfun.com/beanfun_block/generic_handlers/get_webstart_otp.ashx"; let t = BeanFunBlock.LoggedInUserData.WebToken; if (t == "" || t == undefined || t == null) { commonFunctionObject.webToast({ message: "获取Token失败" }); return; } let pollingKey = await getAccountPollingKey(account.sn); if (pollingKey.length <= 0) { commonFunctionObject.webToast({ message: "获取pollingKey失败" }); return; } let secret = await getAccountSecret(); if (secret.length <= 0) { commonFunctionObject.webToast({ message: "获取secret失败" }); return; } url = url + "?sn=" + pollingKey + "&WebToken=" + t + "&SecretCode=" + secret + "&ppppp=F9B45415B9321DB9635028EFDBDDB44B4012B05F95865CB8909B2C851CFE1EE11CB784F32E4347AB7001A763100D90768D8A4E30BCC3E80C"; url = url + "&ServiceCode=610074&ServiceRegion=T9&ServiceAccount=" + account.title + "&CreateTime=" + account.createTime + "&d=" + Date.now(); let resultData = await commonFunctionObject.request("get", url, null); if (resultData.result == "success") { let html = resultData.data; if (html.length <= 0) { commonFunctionObject.webToast({ message: "获取密码令牌失败" }); return; } let arr = html.split(";")[1]; let key = arr.substring(0, 8); let value = arr.substring(8); let crypto_key = CryptoJS.enc.Utf8.parse(key); let valByte = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(value)) let cj = CryptoJS.DES.decrypt(valByte, crypto_key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding, }); let pwd = cj.toString(CryptoJS.enc.Utf8); return pwd.replace(/[^0-9]/ig, ""); } return ""; } //初始化beanfun async function initBeanfun() { var bootstrapCss = GM_getResourceText("bootstrapCss"); GM_addStyle(bootstrapCss); commonFunctionObject.addCommonHtmlCss(); commonFunctionObject.addCommonPopup(); await initAccountInfo(); if (accounts.length <= 0) { commonFunctionObject.webToast({ message: "获取账号信息失败" }); return; } let li = document.createElement('li'); let b = document.createElement('button') b.setAttribute("class", "xs-side-bar-cntr1 btn btn-info"); b.setAttribute("data-toggle", "modal"); b.setAttribute("data-target", "#sBeanfun"); b.setAttribute("id", "startBeanfun"); b.innerHTML = "启动获取密码" li.appendChild(b); $("#BF_divRightButtons ul").prepend(li); initVue(); } //初始化vue function initVue() { const { createApp } = Vue; let app = new Vue({ el: '#app', data: { items: [], pwd: "" }, mounted: function () { this.items = accounts; }, methods: { getPwd: async function (index, e) { let data = this.items.slice()[index] $(e.target).text("获取中") $(e.target).attr("class", "btn btn-warning") $(e.target).attr("disabled", true); //开始获取密码 let pwd = await getDynamicPwd(data); $(e.target).text("获取密码") $(e.target).attr("class", "btn btn-primary") $(e.target).attr("disabled", false); if (pwd.length <= 0) { commonFunctionObject.webToast({ message: "获取动态密码失败" }); return; } this.pwd = pwd; } } }); } initBeanfun();