// ==UserScript== // @name Bilibili直播间挂机助手 // @namespace SeaLoong // @version 1.1 // @description Bilibili直播间自动签到,领瓜子,参加抽奖,完成任务,送礼等 // @author SeaLoong // @include /https?:\/\/live\.bilibili\.com\/\d+/ // @grant none // @run-at document-end // @license MIT License // @downloadURL none // ==/UserScript== (function() { 'use strict'; /* 可修改以下内容用以自定义功能 */ var CONFIG = { USE_SIGN: true, // 自动签到: true:启用, false:不启用 USE_AWARD: true, // 自动领取瓜子: true:启用, false:不启用 USE_LOTTERY: true, // 自动参加抽奖: true:启用, false:不启用 USE_TASK: true, // 自动完成任务: true:启用, false:不启用 USE_GIFT: true, // 自动送礼物: true:启用, false:不启用 GIFT_CONFIG: { // 若启用自动送礼物,则需要设置以下项 SHORT_ROOMID: 0, // 指定直播间ID(即地址中live.bilibili.com/后面的数字), 设置为0则表示自动检查是否有当前直播间头衔,有则切换并送礼 USE_SILVER: false, // 消耗银瓜子来送礼物: true:允许, false:不允许 ONLY_AFTER_23: true // 只允许在23:00后消耗银瓜子送礼物 } }; /* 可修改以上内容用以自定义功能 */ var NAME = 'Bilibili-LiveRoom-HangHelper'; var TaskAward_Running = false; var ToastElement, ToastCount = 0; var room_id_list = []; var lottery_list_last = [], lottery_check_time = 20; var gift_list = null; /* 1:辣条:亲密度+1 3:B坷垃:亲密度+99 4:喵娘:亲密度+52 6:亿元:亲密度+10 7:666:亲密度+? 8:233:亲密度+? 25:小电视:亲密度+12450? 39:节奏风暴:亲密度+1000? 105:火力票:亲密度+20 106:哔哩星:亲密度+20 */ var Info = { short_id: null, uid: null, ruid: null, roomid: null, rnd: null, area_id: null, // area_v2_id area_parent_id: null, old_area_id: null, // areaId csrf_token: function() { return getCookie('bili_jct'); }, today_feed: null, day_limit: null, silver: null, gold: null, mobile_verified: null, medal_list: null, medal_target_id: null, task_list: null, bag_list: null }; var DEBUG = function(arg) { console.debug(arg); }; var API = { ajax: function(settings) { // DEBUG('API.ajax: settings:' + JSON.stringify(settings)); if (settings.xhrFields) { $.extend(settings.xhrFields, { withCredentials: true }); } else { settings.xhrFields = { withCredentials: true }; } $.extend(settings, { url: (settings.url.substr(0, 2) == '//' ? '' : '//api.live.bilibili.com/') + settings.url, type: settings.type || 'GET', crossDomain: true, dataType: settings.dataType || 'json' }); return $.ajax(settings); }, ajaxGetCaptchaKey: function() { return API.ajax({ url: '//www.bilibili.com/plus/widget/ajaxGetCaptchaKey.php?js' }); }, msg: function(roomid, csrf_token) { return API.ajax({ type: 'POST', url: 'ajax/msg', data: { roomid: roomid, csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); }, ajaxCapsule: function(id, ts, platform, player_type) { return API.ajax({ url: 'api/ajaxCapsule' }); }, player: function(id, ts, platform, player_type) { //获取直播流相关信息 return API.ajax({ url: 'api/player', data: { id: id, ts: ts, // HEX platform: platform || 'pc', player_type: player_type || 'web' }, dataType: 'text' }); }, create: function(width, height) { // 生成一个验证码 return API.ajax({ url: 'captcha/v1/Captcha/create', data: { width: width, height: height, _: Date.now() } }); }, topList: function(roomid, page, ruid) { return API.ajax({ url: 'guard/topList', data: { roomid: roomid, page: page, ruid: ruid } }); }, getSuser: function() { return API.ajax({ url: 'msg/getSuser' }); }, refresh: function() { return API.ajax({ url: 'index/refresh?area=all' }); }, get_ip_addr: function() { return API.ajax({ url: 'ip_service/v1/ip_service/get_ip_addr' }); }, ajaxGetMyMedalList: function() { return API.ajax({ url: '//live.bilibili.com/i/ajaxGetMyMedalList' }); }, getuserinfo: function() { return API.ajax({ url: '//live.bilibili.com/user/getuserinfo' }); }, MyInfo: function() { return API.ajax({ url: '//space.bilibili.com/ajax/member/MyInfo' }); }, activity: { mobileActivity: function() { return API.ajax({ url: 'activity/v1/Common/mobileActivity' }); }, roomInfo: function(roomid, ruid) { return API.ajax({ url: 'activity/v1/Common/roomInfo', data: { roomid: roomid, ruid: ruid } }); }, welcomeInfo: function(roomid) { return API.ajax({ url: 'activity/v1/Common/welcomeInfo?roomid=' + roomid }); }, master_invite_task: function() { return API.ajax({ url: 'activity/v1/invite/master_invite_task' }); }, check: function(roomid) { return API.ajax({ url: 'activity/v1/Raffle/check?roomid=' + roomid }); }, join: function(roomid, raffleId) { return API.ajax({ url: 'activity/v1/Raffle/join', data: { roomid: roomid, raffleId: raffleId } }); }, notice: function(roomid, raffleId) { return API.ajax({ url: 'activity/v1/Raffle/notice', data: { roomid: roomid, raffleId: raffleId } }); }, master_limit_tasks: function() { return API.ajax({ url: 'activity/v1/task/master_limit_tasks' }); }, receive_award: function(task_id, csrf_token) { return API.ajax({ type: 'POST', url: 'activity/v1/task/receive_award', data: { task_id: task_id, csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); }, user_limit_tasks: function() { return API.ajax({ url: 'activity/v1/task/user_limit_tasks' }); } }, feed: { getList: function(page, page_size) { return API.ajax({ url: 'feed/v1/feed/getList', data: { page: page, page_size: page_size, _: Date.now() } }); }, heartBeat: function(_cb) { return API.ajax({ url: 'feed/v1/feed/heartBeat', data: { _cb: _cb } }); }, GetUserFc: function(follow) { // follow: 主播uid==ruid return API.ajax({ url: 'feed/v1/Feed/GetUserFc?follow=' + follow }); }, IsUserFollow: function(follow) { // follow: 主播uid==ruid return API.ajax({ url: 'feed/v1/Feed/IsUserFollow?follow=' + follow }); }, }, feed_svr: { notice: function(csrf_token) { return API.ajax({ type: 'POST', url: 'feed_svr/v1/feed_svr/notice', data: { csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); }, my: function(page_size, csrf_token, live_status, type, offset) { return API.ajax({ type: 'POST', url: 'feed_svr/v1/feed_svr/my', data: { live_status: live_status || 0, type: type || 0, page_size: page_size, offset: offset || 0, csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); } }, FreeSilver: { getSurplus: function() { return API.ajax({ url: 'FreeSilver/getSurplus' }); }, getAward: function(time_start, end_time, captcha) { return API.ajax({ url: 'FreeSilver/getAward', data: { time_start: time_start, end_time: end_time, captcha: captcha } }); }, getCurrentTask: function() { return API.ajax({ url: 'FreeSilver/getCurrentTask' }); }, getCaptcha: function(ts, callback) { getBlobDataURL("//api.live.bilibili.com/freeSilver/getCaptcha?ts=" + ts, callback); } }, gift: { bag_list: function() { return API.ajax({ url: 'gift/v2/gift/bag_list' }); }, send: function(uid, gift_id, ruid, gift_num, coin_type, biz_id, rnd, csrf_token, platform, biz_code, storm_beat_id) { return API.ajax({ type: 'POST', url: 'gift/v2/gift/send', data: { uid: uid, gift_id: gift_id, ruid: ruid, gift_num: gift_num, coin_type: coin_type, bag_id: 0, platform: platform || 'pc', biz_code: biz_code || 'live', biz_id: biz_id, //roomid rnd: rnd, storm_beat_id: storm_beat_id || 0, // metadata: metadata, csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); }, bag_send: function(uid, gift_id, ruid, gift_num, bag_id, biz_id, rnd, csrf_token, platform, biz_code, storm_beat_id) { return API.ajax({ type: 'POST', url: 'gift/v2/live/bag_send', data: { uid: uid, gift_id: gift_id, ruid: ruid, gift_num: gift_num, bag_id: bag_id, platform: platform || 'pc', biz_code: biz_code || 'live', biz_id: biz_id, //roomid rnd: rnd, storm_beat_id: storm_beat_id || 0, // metadata: metadata, csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); }, heart_gift_receive: function(roomid, area_v2_id) { return API.ajax({ url: 'gift/v2/live/heart_gift_receive', data: { roomid: roomid, area_v2_id: area_v2_id } }); }, heart_gift_status: function(roomid, area_v2_id) { return API.ajax({ url: 'gift/v2/live/heart_gift_status', data: { roomid: roomid, area_v2_id: area_v2_id } }); }, receive_daily_bag: function() { return API.ajax({ url: 'gift/v2/live/receive_daily_bag' }); }, room_gift_list: function(roomid, area_v2_id) { return API.ajax({ url: 'gift/v2/live/room_gift_list', data: { roomid: roomid, area_v2_id: area_v2_id } }); }, smalltv: { check: function(roomid) { return API.ajax({ url: 'gift/v2/smalltv/check', data: { roomid: roomid } }); }, join: function(roomid, raffleId) { return API.ajax({ url: 'gift/v2/smalltv/join', data: { roomid: roomid, raffleId: raffleId } }); }, notice: function(roomid, raffleId) { return API.ajax({ url: 'gift/v2/smalltv/notice', data: { roomid: roomid, raffleId: raffleId } }); } } }, giftBag: { getSendGift: function() { return API.ajax({ url: 'giftBag/getSendGift' }); }, sendDaily: function() { return API.ajax({ url: 'giftBag/sendDaily' }); } }, i: { ajaxGetAchieve: function(page, pageSize, type, status, category, keywords) { return API.ajax({ url: 'i/api/ajaxGetAchieve', data: { type: type || 'normal', // or'legend' status: status || 0, category: category || 'all', keywords: keywords, page: page, pageSize: pageSize || 6 } }); }, ajaxCancelWear: function() { return API.ajax({ url: 'i/ajaxCancelWear' }); }, ajaxWearFansMedal: function(medal_id) { return API.ajax({ url: 'i/ajaxWearFansMedal?medal_id=' + medal_id }); }, following: function(page, pageSize) { return API.ajax({ url: 'i/api/following', data: { page: page, pageSize: pageSize } }); }, guard: function(page, pageSize) { return API.ajax({ url: 'i/api/guard', data: { page: page, pageSize: pageSize } }); }, liveinfo: function() { return API.ajax({ url: 'i/api/liveinfo' }); }, medal: function(page, pageSize) { return API.ajax({ url: 'i/api/medal', data: { page: page, pageSize: pageSize } }); }, operation: function(page) { return API.ajax({ url: 'i/api/operation?page=' + page }); }, taskInfo: function() { return API.ajax({ url: 'i/api/taskInfo' }); } }, live: { getRoomKanBanModel: function(roomid) { return API.ajax({ url: 'live/getRoomKanBanModel?roomid' + roomid }); }, rankTab: function(roomid) { return API.ajax({ url: 'live/rankTab?roomid=' + roomid }); }, roomAdList: function() { return API.ajax({ url: 'live/roomAdList' }); } }, live_user: { get_anchor_in_room: function(roomid) { return API.ajax({ url: 'live_user/v1/UserInfo/get_anchor_in_room?roomid=' + roomid }); }, get_info_in_room: function(roomid) { return API.ajax({ url: 'live_user/v1/UserInfo/get_info_in_room?roomid=' + roomid }); }, get_weared_medal: function(uid, target_id, csrf_token, source) { return API.ajax({ type: 'POST', url: 'live_user/v1/UserInfo/get_weared_medal', data: { source: source || 1, uid: uid, target_id: target_id, // roomid csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); } }, lottery: { getRoomActivityByRoomid: function(roomid) { return API.ajax({ url: 'lottery/v1/box/getRoomActivityByRoomid?roomid=' + roomid }); }, check: function(roomid) { return API.ajax({ url: 'lottery/v1/Storm/check?roomid=' + roomid }); }, join: function(id, color, captcha_token, captcha_phrase, csrf_token) { // 加入节奏风暴 return API.ajax({ type: 'POST', url: 'lottery/v1/Storm/join', data: { id: id, color: color, captcha_token: captcha_token, captcha_phrase: captcha_phrase, csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); } }, rankdb: { roomInfo: function(ruid, roomid, areaId) { return API.ajax({ url: 'rankdb/v1/Common/roomInfo', data: { ruid: ruid, roomid: roomid, areaId: areaId } }); } }, room: { get_info: function(room_id, from) { return API.ajax({ url: 'room/v1/Room/get_info', data: { room_id: room_id, from: from || 'room' } }); }, playUrl: function(cid, quality, platform) { return API.ajax({ url: 'room/v1/Room/playUrl', data: { cid: cid, // roomid quality: quality || '0', platform: platform || 'web' } }); }, room_entry_action: function(room_id, csrf_token, platform) { return API.ajax({ type: 'POST', url: 'room/v1/Room/room_entry_action', data: { room_id: room_id, platform: platform || 'pc', csrf_token: typeof csrf_token == 'function' ? csrf_token() : csrf_token } }); }, room_init: function(id) { return API.ajax({ url: 'room/v1/Room/room_init?id=' + id }); } }, sign: { doSign: function() { return API.ajax({ url: 'sign/doSign' }); }, GetSignInfo: function() { return API.ajax({ url: 'sign/GetSignInfo' }); }, getLastMonthSignDays: function() { return API.ajax({ url: 'sign/getLastMonthSignDays' }); } }, user: { getWear: function(uid) { return API.ajax({ url: 'user/v1/user_title/getWear?uid=' + uid }); }, userOnlineHeart: function() { return API.ajax({ type: 'POST', url: 'User/userOnlineHeart' }); }, getUserInfo: function(ts) { // ms return API.ajax({ url: 'User/getUserInfo?ts=' + ts }); } }, YearWelfare: { checkFirstCharge: function() { return API.ajax({ url: 'YearWelfare/checkFirstCharge' }); }, inviteUserList: function() { return API.ajax({ url: 'YearWelfare/inviteUserList/1' }); } } }; function ts_s() { return Math.floor(Date.now() / 1000); } function ts_ms() { return Date.now(); } function getCookie(name) { var arr, reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); if ((arr = document.cookie.match(reg))) { return unescape(arr[2]); } else { return null; } } function setCookie(name, value, seconds) { seconds = seconds || 0; var expires = ''; if (parseInt(seconds) !== 0) { var date = new Date(); date.setTime(date.getTime() + (seconds * 1000)); expires = '; expires=' + date.toGMTString(); } document.cookie = name + '=' + escape(value) + expires + '; path=/'; } function getBlobDataURL(url, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.responseType = 'blob'; xhr.withCredentials = true; xhr.onload = function() { var reader = new FileReader(); reader.onload = function() { callback(reader.result); }; reader.readAsDataURL(xhr.response); }; xhr.send(); } /* 验证码识别算法来自互联网,作者未知 该算法已被简单修改 */ function getChar(t) { if (t.sum <= 50) return '-'; if (t.sum > 120 && t.sum < 135) return '+'; if (t.sum > 155 && t.sum < 162) return 1; if (t.sum > 189 && t.sum < 195) return 7; if (t.sum > 228 && t.sum < 237) return 4; if (t.sum > 250 && t.sum < 260) return 2; if (t.sum > 286 && t.sum < 296) return 3; if (t.sum > 303 && t.sum < 313) return 5; if (t.sum > 335 && t.sum < 342) return 8; if (t.sum > 343 && t.sum < 350) { if (t.first > 24 && t.last > 24) return 0; if (t.first < 24 && t.last > 24) return 9; if (t.first > 24 && t.last < 24) return 6; } } function calcImg() { /* * 1.验证码图片->二维点阵 * 2.二维点阵->横向一维压缩 * 3.分析并计算 */ var ctx = $('#' + NAME + '_canvas')[0].getContext("2d"); var img = $('#' + NAME + '_img')[0]; ctx.drawImage(img, 0, 0, 120, 40); var pixels = ctx.getImageData(0, 0, 120, 40).data; var pix = []; var i = 0; var j = 0; var n = 0; for (i = 1; i <= 40; i++) { pix[i] = []; for (j = 1; j <= 120; j++) { var c = 1; if (pixels[n] - (-pixels[n + 1]) - (-pixels[n + 2]) > 200) { //判断RGB之和是否大于200(接近白色) c = 0; } n += 4; pix[i][j] = c; } } //二维点阵pix[40][120] var line = []; line[0] = 0; for (i = 1; i <= 120; i++) { line[i] = 0; for (j = 1; j <= 40; j++) { line[i] += pix[j][i]; } } //一维line[120] var temp = []; n = 0; for (i = 1; i <= 120; i++) { if (line[i] > 0 && line[i - 1] === 0) { n++; temp[n] = {}; temp[n].first = line[i]; temp[n].sum = 0; } if (line[i] > 0) { temp[n].sum += line[i]; } if (line[i - 1] > 0 && line[i] === 0) { temp[n].last = line[i - 1]; } } if (n == 4) { var result = 0; var a = getChar(temp[1]) * 10 - (-getChar(temp[2])); var b = getChar(temp[4]); if (getChar(temp[3]) == '+') { result = a - (-b); } else { result = a - b; } DEBUG('TaskAward: calcImg: 识别验证码: ' + getChar(temp[1]) + getChar(temp[2]) + ' ' + getChar(temp[3]) + ' ' + getChar(temp[4]) + ' = ' + result); return result; } else { return null; } } var liveQuickLogin = function() { if (!getCookie('DedeUserID') && !getCookie('LIVE_LOGIN_DATA')) { try { if (!window.biliQuickLogin) { $.getScript('https://static-s.bilibili.com/account/bili_quick_login.js', function(response, status) { if (status === 'success') login(); }); } else { login(); } } catch (tryErr) { throw new Error(tryErr); } } function login() { if (window.biliQuickLogin) { window.biliQuickLogin(function() { window.location.reload(); }); throw 'Bilibili Live: 您还未登陆.'; } else { throw 'Bilibili Live: 快速登录脚本加载失败.'; } } }; function giftIDtoFeed(gift_id) { for (var i = gift_list.length - 1; i >= 0; i--) { if (gift_list[i].id === gift_id) { return Math.floor(gift_list[i].price / 100); } } return 0; } function toast(t, e, n, r) { if ('boolean' == typeof n) n = 'info'; var o = document.createDocumentFragment(), a = document.createElement('div'); if ('success' !== (n = n || 'info') && 'caution' !== n && 'error' !== n && 'info' !== n) throw new Error(i + ' 在使用 Link Toast 时必须指定正确的类型: success || caution || error || info'); if (a.innerHTML = '' + e + '', a.className = 'link-toast ' + n + ' ' + (r ? 'fixed' : ''), !t.className && !t.attributes) throw new Error(i + ' 传入 element 不是有效节点.'); var c = t.getBoundingClientRect(), s = c.left, u = c.top, l = c.width, f = c.height, p = document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft; a.style.left = s + l + p + 'px'; var d = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop; a.style.top = u + f + d + ToastCount * 40 + 'px'; setTimeout((function() { a.className += ' out'; setTimeout((function() { // TODO ToastCount = 0; a.parentNode.removeChild(a); }), 350); }), 3e3); o.appendChild(a); document.body.appendChild(o); var h = document.body.offsetWidth, v = a.getBoundingClientRect().left, m = a.offsetWidth; if (h - m - v < 0) a.style.left = h - m - 10 + p + 'px'; ToastCount += 1; } /* window.BilibiliLive.ANCHOR_UID window.BilibiliLive.COLORFUL_LOGGER window.BilibiliLive.INIT_TIME window.BilibiliLive.RND === window.DANMU_RND window.BilibiliLive.ROOMID window.BilibiliLive.SHORT_ROOMID window.BilibiliLive.UID window.captcha_key window.Yb */ function Init() { // liveQuickLogin(); var _interval = setInterval(function() { if (window.BilibiliLive) { DEBUG('Init: BilibiliLive: ' + JSON.stringify(window.BilibiliLive)); if (parseInt(window.BilibiliLive.UID) !== 0) { Info.short_id = window.BilibiliLive.SHORT_ROOMID; Info.uid = window.BilibiliLive.UID; Info.roomid = window.BilibiliLive.ROOMID; Info.ruid = window.BilibiliLive.ANCHOR_UID; Info.rnd = window.BilibiliLive.RND; // API.MyInfo().done(function(response) { // if (response.status === true) { // Info.mobile_verified = response.data.mobile_verified; // } // }); room_id_list[Info.short_id] = Info.roomid; if (CONFIG.USE_AWARD) { var _interval_treasure_box = setInterval(function() { var _treasure_box = $('div.treasure-box.p-relative[id!=' + NAME + '_div_box]'); if (_treasure_box[0]) { _treasure_box.attr('style', "display:none"); var div = $('
'); var b_box = $('
自动
领取中
'); b_box.css({ 'max-width': '40px', 'padding': '2px 3px', 'margin-top': '3px', 'font-size': '12px', 'color': '#fff', 'background-color': 'rgba(0,0,0,.5)', 'border-radius': '10px' }); var img = $(''); var canvas = $(''); div.append(b_box); div.append(img); div.append(canvas); $('div.vertical-middle.dp-table.section.left-part div.dp-table-cell.v-middle').append(div); clearInterval(_interval_treasure_box); } }, 200); } if (CONFIG.USE_GIFT && (CONFIG.GIFT_CONFIG.SHORT_ROOMID === 0 || CONFIG.GIFT_CONFIG.SHORT_ROOMID == Info.short_id)) { API.live_user.get_weared_medal(Info.uid, Info.roomid, Info.csrf_token).done(function(response) { DEBUG('Init: get_weared_medal: ' + JSON.stringify(response)); if (response.code === 0) { Info.medal_target_id = response.data.target_id; Info.today_feed = parseInt(response.data.today_feed); Info.day_limit = response.data.day_limit; Info.old_area_id = response.data.area; Info.area_id = response.data.area_v2_id; Info.area_parent_id = response.data.area_v2_parent_id; API.gift.room_gift_list(Info.roomid, Info.area_id).done(function(response) { // DEBUG('Init: room_gift_list: ' + JSON.stringify(response)); if (response.code === 0) { gift_list = response.data; } }); } }); API.live_user.get_info_in_room(Info.room_id).done(function(response) { DEBUG('Init: get_info_in_room: ' + JSON.stringify(response)); if (response.code === 0) { Info.silver = response.data.wallet.silver; Info.gold = response.data.wallet.gold; Info.mobile_verified = response.data.info.mobile_verified; } }); } DEBUG('Init: Info: ' + JSON.stringify(Info)); ToastElement = $('
'); $('div.vertical-middle.dp-table.section.left-part div.dp-table-cell.v-middle').append(ToastElement); ToastElement = ToastElement[0]; var str = []; if (CONFIG.USE_SIGN) str.push('自动签到'); if (CONFIG.USE_AWARD) str.push('自动领取瓜子'); if (CONFIG.USE_LOTTERY) str.push('自动参加抽奖'); if (CONFIG.USE_TASK) str.push('自动完成任务'); if (CONFIG.USE_GIFT) str.push('自动送礼'); if (str.length) str = str.join(','); else str = '无'; toast(ToastElement, '助手已启用功能:' + str, 'info'); TaskStart(); } else { // 未登录 toast(ToastElement, '你还没有登录,助手无法使用!', 'error'); } clearInterval(_interval); } }, 1e3); } function TaskLogWatcher(callback) { var logs_last_length = 0; setInterval(function() { if (logs_last_length !== window.Yb.length) { var logs_new = window.Yb.slice(logs_last_length, window.Yb.length); if (logs_new && logs_new.length) { logs_last_length = window.Yb.length; callback(logs_new); } } }, 1000); } function SmallTV(room_id, callback) { API.gift.smalltv.check(room_id).done(function(response) { // 检查是否有小电视抽奖 DEBUG('TaskLottery: smalltv.check: ' + JSON.stringify(response)); if (response.code === 0) { response.data.forEach(function(v) { if (v.status === 1) { // 可以参加 API.gift.smalltv.join(room_id, v.raffleId).done(function(response) { DEBUG('TaskLottery: smalltv.join: ' + JSON.stringify(response)); if (response.code === 0) { setTimeout(function() { SmallTVNotice(room_id, response.data.raffleId, function(msg) { toast(ToastElement, msg, 'info'); }); }, response.data.time * 1e3 + 9e3); callback(); } }); } }); } }); } function Raffle(room_id, callback) { API.activity.check(room_id).done(function(response) { // 检查是否有活动抽奖 DEBUG('TaskLottery: activity.check: ' + JSON.stringify(response)); if (response.code === 0) { response.data.forEach(function(v) { if (v.status === 1) { API.activity.join(room_id, v.raffleId).done(function(response) { // DEBUG('TaskLottery: activity.join: ' + JSON.stringify(response)); if (response.code === 0) { setTimeout(function() { RaffleNotice(room_id, response.data.raffleId, function(msg) { toast(ToastElement, msg, 'info'); }); }, response.data.time * 1e3 + 9e3); callback(); } }); } }); } }); } function SmallTVNotice(room_id, raffleId, callback) { API.gift.smalltv.notice(room_id, raffleId).done(function(response) { DEBUG('TaskLottery: smalltv.notice: ' + JSON.stringify(response)); if (response.code === 0 && response.data.status !== 3) { if (parseInt(response.data.gift_id) === -1 && !response.data.gift_name) { callback(response.msg); } else { callback('直播间【' + room_id + '】小电视抽奖结果:' + response.data.gift_name + '*' + response.data.gift_num); } } else { // 还未开奖或其他情况 setTimeout(function() { SmallTVNotice(room_id, raffleId, callback); }, 5e3); } }); } function RaffleNotice(room_id, raffleId, callback) { API.activity.notice(room_id, raffleId).done(function(response) { DEBUG('TaskLottery: activity.notice: ' + JSON.stringify(response)); if (response.code === 0) { if (parseInt(response.data.gift_id) === -1) { callback(response.msg); } else { callback('直播间【' + room_id + '】活动抽奖结果:' + response.data.gift_name + '*' + response.data.gift_num); } } else { // 还未开奖或其他情况 setTimeout(function() { RaffleNotice(room_id, raffleId, callback); }, 5e3); } }); } function Award(callback) { API.FreeSilver.getCaptcha(ts_ms(), function(dataURL) { var img = $('#' + NAME + '_img')[0]; img.onload = function() { API.FreeSilver.getAward(ts_s() - 10, ts_s(), calcImg()).done(function(response) { DEBUG('TaskAward: getAward: ' + JSON.stringify(response)); if (response.code === 0) { // 领取瓜子成功 toast(ToastElement, '领取瓜子成功,本次领取了 ' + response.data.awardSilver + ' 银瓜子', 'success'); } else { toast(ToastElement, response.msg, 'error'); } callback(); }); }; img.src = dataURL; }); } function Lottery() { var lottery_list = [], lottery_list_temp = [], overlap_index = Infinity; $('div.chat-item.system-msg div.msg-content a.link').each(function(index, el) { var matched = el.pathname.match(/^\/(\d+)/); if (matched && matched[1]) { var short_id = parseInt(matched[1]); lottery_list_temp.push(short_id); } }); lottery_list_temp.forEach(function(v, i) { if (i === 0) { var index = lottery_list_last.indexOf(v); if (index > -1) { overlap_index = lottery_list_last.length - index; } else { overlap_index = 0; lottery_list.push(v); } } else if (i >= overlap_index) { lottery_list.push(v); } }); lottery_list_last = lottery_list_temp; lottery_list_temp = lottery_list; lottery_list = []; lottery_list_temp.forEach(function(v) { if (lottery_list.indexOf(v) === -1) lottery_list.push(v); }); DEBUG('TaskLottery: Lottery: last: ' + lottery_list_last.toString()); DEBUG('TaskLottery: Lottery: list: ' + lottery_list.toString()); // 根据可抽奖的房间数自动调整检测周期 if (lottery_list.length > 11) { lottery_check_time = 3; } else if (lottery_list.length > 9) { lottery_check_time = 6; } else if (lottery_list.length > 6) { lottery_check_time = 10; } else if (lottery_list.length > 1) { lottery_check_time = 15; } else { lottery_check_time = 20; } lottery_list.forEach(function(short_id) { if (short_id > 0) { var room_id = room_id_list[short_id]; if (room_id > 0) { SmallTV(room_id, function() { toast(ToastElement, '已参加直播间【' + room_id + '】的小电视抽奖', 'success'); }); Raffle(room_id, function() { toast(ToastElement, '已参加直播间【' + room_id + '】的活动抽奖', 'success'); }); } else { API.room.room_init(short_id).done(function(response) { DEBUG('TaskLottery: room_init: ' + JSON.stringify(response)); if (response.code === 0) { room_id = response.data.room_id; room_id_list[short_id] = room_id; SmallTV(room_id, function() { toast(ToastElement, '已参加直播间【' + room_id + '】的小电视抽奖', 'success'); }); Raffle(room_id, function() { toast(ToastElement, '已参加直播间【' + room_id + '】的活动抽奖', 'success'); }); } }); } } }); setTimeout(Lottery, lottery_check_time * 1e3); } function TaskSign() { API.sign.GetSignInfo().done(function(response) { DEBUG('TaskSign: GetSignInfo: ' + JSON.stringify(response)); if (response.code === 0) { if (response.data.status === 0) { // 未签到 API.sign.doSign().done(function(response) { DEBUG('TaskSign: doSign: ' + JSON.stringify(response)); if (response.code === 0) { // 签到成功 toast(ToastElement, response.data.text, 'success'); } else { toast(ToastElement, response.data.text, 'error'); } }); } else if (response.data.status === 1) { // 已签到 } } }); } function TaskAward_newTask() { API.FreeSilver.getCurrentTask().done(function(response) { DEBUG('TaskAward: getCurrentTask: ' + JSON.stringify(response)); if (response.code === 0) { // 获取任务成功 if (parseInt(response.data.minute) !== 0) { setTimeout(TaskAward, response.data.minute * 60e3 + 5e3); TaskAward_Running = true; } } else if (response.code === -10017) { toast(ToastElement, response.msg, 'info'); // 今天所有的宝箱已经领完! var _interval_div_b_box = setInterval(function() { var _div_b_box = $('#' + NAME + '_div_b_box'); if (_div_b_box[0]) { _div_b_box.html('今日
已领完'); clearInterval(_interval_div_b_box); } }, 200); } else { toast(ToastElement, response.msg, 'info'); } }); } function TaskAward() { if (TaskAward_Running) Award(TaskAward_newTask); else TaskAward_newTask(); } function TaskLottery() { setTimeout(Lottery, 3e3); } function TaskReceiveAward(task_id) { API.activity.receive_award(task_id, Info.csrf_token).done(function(response) { // DEBUG('TaskTask: receive_award: ' + JSON.stringify(response)); if (response.code === 0) { // 完成任务 toast(ToastElement, '完成任务:' + task_id, 'info'); } }); } function Task() { toast(ToastElement, '检查任务情况,1小时后再次检查', 'info'); API.i.taskInfo().done(function(response) { DEBUG('TaskTask: taskInfo: ' + JSON.stringify(response)); if (response.code === 0) { for (var key in response.data) { if (response.data[key].task_id && response.data[key].status) { // 当前对象是任务且任务可完成 TaskReceiveAward(response.data[key].task_id); } } } }); API.activity.user_limit_tasks().done(function(response) { DEBUG('TaskTask: user_limit_tasks: ' + JSON.stringify(response)); if (response.code === 0) { for (var key in response.data) { if (response.data[key].task_id && response.data[key].status) { // 当前对象是任务且任务可完成 TaskReceiveAward(response.data[key].task_id); } } } }); API.activity.master_limit_tasks().done(function(response) { DEBUG('TaskTask: master_limit_tasks: ' + JSON.stringify(response)); if (response.code === 0) { for (var key in response.data) { if (response.data[key].task_id && response.data[key].status) { // 当前对象是任务且任务可完成 TaskReceiveAward(response.data[key].task_id); } } } }); setTimeout(Task, 3600e3); } function TaskTask() { setTimeout(Task, 5e3); } function Gift() { /* 任务周期1小时,脚本运行后立即执行一次任务 判断是否佩戴当前主播的头衔 否:判断是否拥有当前主播的头衔,有则自动切换,没有则停止任务 是:刷新当前亲密度上限和已喂养亲密度 可以继续喂养则刷新背包,不可以则停止任务 按照过期时间(天)从短到长排序,同一天按照礼物提供的亲密度从大到小排序 按已排序的背包顺序送礼,直到亲密度已满或无法送礼,如:亲密度还可增加9但没有辣条,此时不送礼物 可选:消耗银瓜子购买辣条送礼,直到亲密度已满或银瓜子不足 可选:当前时间超过23:00时才消耗银瓜子 */ API.live_user.get_weared_medal(Info.uid, Info.roomid, Info.csrf_token).done(function(response) { DEBUG('TaskGift: get_weared_medal: ' + JSON.stringify(response)); if (response.code === 0) { Info.today_feed = parseInt(response.data.today_feed); Info.day_limit = response.data.day_limit; if (Info.day_limit - Info.today_feed > 0) { toast(ToastElement, '今日亲密度未满,开始送礼', 'info'); API.gift.bag_list().done(function(response) { DEBUG('TaskGift: bag_list: ' + JSON.stringify(response)); if (response.code === 0) { Info.bag_list = response.data.list; var remain_feed = Info.day_limit - Info.today_feed; // DEBUG('TaskGift: remain_feed: ' + remain_feed + ',day_limit:' + Info.day_limit + ',today_feed:' + Info.today_feed); Info.bag_list.forEach(function(v) { if (remain_feed) { var feed_single = giftIDtoFeed(v.gift_id); // DEBUG('TaskGift: Before bag_send: remain_feed:' + remain_feed + ',giftIDtoFeed(v.gift_id):' + giftIDtoFeed(v.gift_id) + ',' + JSON.stringify(v)); if (feed_single > 0) { var feed_num = Math.floor(remain_feed / feed_single); if (feed_num > v.gift_num) { feed_num = v.gift_num; } // DEBUG('TaskGift: Before bag_send: remain_feed:' + remain_feed + ',feed_num:' + feed_num + ',feed_single:' + feed_single); if (feed_num > 0) { API.gift.bag_send(Info.uid, v.gift_id, Info.ruid, feed_num, v.bag_id, Info.roomid, Info.rnd, Info.csrf_token).done(function(response) { DEBUG('TaskGift: bag_send: ' + JSON.stringify(response)); if (response.code === 0) { // 送礼成功 Info.rnd = response.data.rnd; toast(ToastElement, '背包送礼成功:送出' + feed_num + '个' + v.gift_name, 'success'); } else { toast(ToastElement, '背包送礼异常:' + response.msg, 'error'); } }); remain_feed -= feed_num * feed_single; } } } }); if (CONFIG.GIFT_CONFIG.USE_SILVER && remain_feed > 0) { if (CONFIG.GIFT_CONFIG.ONLY_AFTER_23) { DEBUG('TaskGift: 检查当前时间: ' + (new Date()).getHours()); if ((new Date()).getHours() < 23) { toast(ToastElement, '当前时间未到23:00,1小时后再次检查送礼', 'info'); setTimeout(Gift, 3600e3); return; } } var feed_num = Math.floor(remain_feed); if (feed_num > 0) { if (feed_num * 100 > Info.silver) { feed_num = Math.floor(Info.silver / 100); } API.gift.send(Info.uid, 1, Info.ruid, feed_num, 'silver', Info.roomid, Info.rnd, Info.csrf_token).done(function(response) { DEBUG('TaskGift: send: ' + JSON.stringify(response)); if (response.code === 0) { // 送礼成功 Info.rnd = response.data.rnd; Info.silver = response.data.extra.wallet.silver; toast(ToastElement, '银瓜子送礼成功,送出' + feed_num + '个辣条,剩余银瓜子:' + Info.silver, 'success'); } else { toast(ToastElement, '银瓜子送礼异常,' + response.msg, 'error'); } }); remain_feed -= feed_num; } } if (remain_feed > 0) { toast(ToastElement, '今日亲密度未满,1小时后再次检查送礼', 'info'); setTimeout(Gift, 3600e3); } else { toast(ToastElement, '今日亲密度已满,送礼任务停止', 'info'); } } else { toast(ToastElement, '获取背包异常,' + response.msg, 'error'); } }); } } else { toast(ToastElement, '获取亲密度异常,' + response.msg, 'error'); } }); } function TaskGift() { if (Info.medal_target_id !== Info.ruid) { API.i.medal(1, 10).done(function(response) { DEBUG('TaskGift: medal: ' + JSON.stringify(response)); if (response.code === 0) { Info.medal_list = response.data.fansMedalList; Info.medal_list.forEach(function(v) { if (v.target_id === Info.ruid) { API.i.ajaxWearFansMedal(v.medal_id).done(function(response) { DEBUG('TaskGift: ajaxWearFansMedal: ' + JSON.stringify(response)); setTimeout(Gift, 6e3); toast(ToastElement, '已自动切换当前头衔', 'info'); }); } }); } }); } else { setTimeout(Gift, 6e3); } } function TaskStart() { setTimeout(function() { if (CONFIG.USE_SIGN) TaskSign(); if (CONFIG.USE_AWARD) TaskAward(); if (CONFIG.USE_LOTTERY) TaskLottery(); if (CONFIG.USE_TASK) TaskTask(); if (CONFIG.USE_GIFT && (CONFIG.GIFT_CONFIG.SHORT_ROOMID === 0 || CONFIG.GIFT_CONFIG.SHORT_ROOMID == Info.short_id)) TaskGift(); }, 3e3); } $(document).ready(function() { DEBUG(NAME + ': Ready'); Init(); }); })();