您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
同步CC98抽卡游戏的收藏至CC98签名档
// ==UserScript== // @name My Collection to CC98 QMD // @namespace http://tampermonkey.net/ // @version 0.2 // @description 同步CC98抽卡游戏的收藏至CC98签名档 // @author Q&A // @match https://card.cc98.org/Home/Collection // @match https://www.cc98.org // @icon https://www.google.com/s2/favicons?sz=64&domain=cc98.org // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js // @resource toastrCSS https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.css // @grant GM_setValue // @grant GM_getValue // @grant GM_getResourceText // @grant GM_addStyle // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== /* globals html2canvas, toastr */ (function() { 'use strict'; GM_addStyle(GM_getResourceText("toastrCSS")); let toastr_title = "My Collection to CC98 QMD"; toastr.options.timeOut = 5000; toastr.options.extendedTimeOut = 5000; toastr.options.newestOnTop = false; toastr.options.progressBar = true; toastr.options.positionClass = "toast-top-center"; // 从 www.cc98.org 的 localStorage 获取 accessToken if ("www.cc98.org" === location.host) { if(!GM_getValue("update_token", false)) return; let access_token = localStorage.getItem("accessToken"); if(null !== access_token) { GM_setValue("access_token", access_token.slice(4)); toastr.success("获取accessToken成功!",toastr_title); GM_setValue("update_token", false); } else { toastr.error("获取accessToken失败!",toastr_title); } return; } // 日期格式化字符串 Date.prototype.format = function(fmt) { var o = { "M+" : this.getMonth()+1, "d+" : this.getDate(), "h+" : this.getHours(), "m+" : this.getMinutes(), "s+" : this.getSeconds(), "q+" : Math.floor((this.getMonth()+3)/3), "S" : this.getMilliseconds() }; if(/(y+)/.test(fmt)) { fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); } for(var k in o) { if(new RegExp("("+ k +")").test(fmt)){ fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); } } return fmt; } // base64转文件 function dataURLtoFile(base64Str, fileName) { var arr = base64Str.split(','), mime = arr[0].match(/:(.*?);/)[1], //base64解析出来的图片类型 bstr = atob(arr[1]), //对base64串进行操作,去掉url头,并转换为byte atob为window内置方法 len = bstr.length, ab = new ArrayBuffer(len), //将ASCII码小于0的转换为大于0 u8arr = new Uint8Array(ab); // while (len--) { u8arr[len] = bstr.charCodeAt(len) } // 创建新的 File 对象实例[utf-8内容,文件名称或者路径,[可选参数,type:文件中的内容mime类型]] return new File([u8arr], fileName, { type: mime }) } // 添加按钮 document.getElementsByClassName("alert alert-info")[0].innerHTML += "<a href=\"javascript:myCollection2CC98()\" class=\"alert-link\">单击这里</a>同步我的收藏至CC98签名档。" unsafeWindow.myCollection2CC98 = function() { console.log("My Collection to CC98 QMD!"); let card_group = document.getElementsByClassName("card-group")[0]; html2canvas(card_group).then(canvas => { // 生成图片 var image = new Image(); image.src = canvas.toDataURL("image/png"); let image_file = dataURLtoFile(image.src, "card-group.png"); // 获取accessToken let access_token = GM_getValue("access_token", ""); if("" === access_token) { GM_setValue("update_token", true); toastr.error("【0/3】请<button onclick=\"window.open('https://www.cc98.org')\">点我打开cc98.org</button>获取accessToken!",toastr_title); return; } toastr.success("【1/3】已成功获取accessToken!(token: "+access_token.slice(0,5) + "……" + access_token.slice(-5)+")",toastr_title); // 上传文件至cc98服务器,获取图片URL var form = new FormData(); form.append("files", image_file, "card-group.png"); GM_xmlhttpRequest({ method: "POST", url: "https://api.cc98.org/file", headers: { Authorization: access_token }, data: form, onload: function(res){ if(res.status === 200){ let img_url = JSON.parse(res.response)[0]; toastr.success("【2/3】已成功上传图片至98服务器!(URL: " + img_url +")",toastr_title); // 更新签名档 GM_xmlhttpRequest({ method: "GET", url: "https://api.cc98.org/me", headers: { Authorization: access_token }, onload: function(res){ if(res.status == 200) { let me = JSON.parse(res.response); let birthday = new Date(me.birthday); let update_me = { Birthday: birthday.format("yyyy-MM-dd"), DisplayTitleId: me.displatTitleId?me.displatTitleId:0, EmailAddress: me.emailAddress, Gender: me.gender, Introduction: me.introduction, QQ: me.qq, SignatureCode: "[img]" + img_url + "[/img]\n[right]Updated at " + new Date().format("yy-MM-dd hh:mm:ss")+" | Powered by [url=https://greasyfork.org/zh-CN/scripts/449683][b][u]My Collection to CC98 QMD[/u][/b][/url][/right]", birthdayDay: birthday.getDate(), birthdayMonth: birthday.getMonth()+1, birthdayYear: birthday.getFullYear(), userTitleIds: me.userTitleIds } GM_xmlhttpRequest({ method: "PUT", url: "https://api.cc98.org/me", headers: { Authorization: access_token, "Content-Type": "application/json" }, data: JSON.stringify(update_me), onload: function(res) { if(res.status == 200) { toastr.success("【3/3】已成功更新个人资料,请<button onclick=\"window.open('https://www.cc98.org/usercenter')\">点我打开cc98.org</button>查看!",toastr_title) } else { console.log(res); toastr.error("【2/3】更新个人资料失败,请重试!",toastr_title); } } }); } else { console.log(res); toastr.error("【2/3】获取个人资料失败,请重试!",toastr_title); } } }); }else{ console.log(res); GM_setValue("update_token", true); toastr.error("【1/3】上传失败,请<button onclick=\"window.open('https://www.cc98.org')\">点我打开cc98.org</button>重新获取accessToken!",toastr_title); } }, onerror : function(err){ console.log(err); } }); }); } })();