检测其乐论坛福利放送版块的赠key剩余数量/时间
- /* eslint-disable new-cap */
- // ==UserScript==
- // @name Giveaway Left Check
- // @namespace Giveaway-Left-Check
- // @version 0.5
- // @description 检测其乐论坛福利放送版块的赠key剩余数量/时间
- // @author HCLonely
- // @iconURL https://auto-task.hclonely.com/img/favicon.ico
- // @homepage https://github.com/HCLonely/user.js
- // @supportURL https://github.com/HCLonely/user.js/issues
- // @include *://keylol.com/*
- // @require https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js
- // @run-at document-end
- // @grant GM_xmlhttpRequest
- // @grant GM_addStyle
- // @connect marvelousga.com
- // @connect grabfreegame.com
- // @connect bananagiveaway.com
- // @connect gamehag.com
- // @connect prys.revadike.com
- // @connect takekey.ru
- // @connect alienwarearena.com
- // @connect giveaway.su
- // @connect givekey.ru
- // @connect store.cubejoy.com
- // @connect cart.cubejoy.com
- // @connect itch.io
- // ==/UserScript==
- (function () {
- 'use strict';
- const getTime = (dateStr) => {
- const endDate = new Date(dateStr).getTime();
- const nowDate = new Date().getTime();
- if (nowDate > endDate) return 0;
- const restSec = endDate - nowDate;
- const day = parseInt(restSec / (60 * 60 * 24 * 1000), 10);
- const hour = parseInt(restSec / (60 * 60 * 1000) % 24, 10);
- const min = parseInt(restSec / (60 * 1000) % 60, 10);
- const sec = parseInt(restSec / 1000 % 60, 10);
- return {
- time: `${day > 0 ? `${day} 天 ` : ''} ${hour}小时${min}分${sec}秒`,
- // eslint-disable-next-line no-nested-ternary
- class: day > 0 ? 'lk-green' : (hour > 1 ? 'lk-yellow' : 'lk-red')
- };
- };
- const getClass = (left) => {
- const leftKey = parseInt(left, 10);
- if (leftKey > 99) {
- return 'lk-green';
- } else if (leftKey > 0 && leftKey < 100) {
- return 'lk-yellow';
- }
- return 'lk-red';
- };
- const checkMarvelousga = (id, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url: 'https://marvelousga.com/',
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const a = $(`<div>${response.responseText}</div>`).find(`a[href*="${id}"]`);
- if (a.length > 0) {
- const [leftKey] = a.parent().children('small')
- .text()
- .trim()
- .match(/[\d]+/);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(leftKey)}" title="剩余key数量">${leftKey}</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="剩余key数量">0</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkGrabfreegame = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('#giveaway .left>b');
- if (counter.length > 0) {
- const leftKey = counter.text().trim();
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(leftKey)}" title="剩余key数量">${leftKey}</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="剩余key数量">0</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkGamehag = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('div.giveaway-counter')
- .not(':contains("day")')
- .find('.strong');
- if (counter.length > 0) {
- const leftKey = counter.text().trim();
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(leftKey)}" title="剩余key数量">${leftKey}</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="剩余key数量">0</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkPrys = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('#header :contains("left")');
- if (counter.length > 0) {
- const [, leftKey] = counter.text().trim()
- .match(/\(([\d]+).*\)/);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(leftKey)}" title="剩余key数量">${leftKey}</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="剩余key数量">0</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkTakekey = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('span.text-muted:contains("Left")');
- if (counter.length > 0) {
- const [leftKey] = counter.text().trim()
- .match(/[\d]+/);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(leftKey)}" title="剩余key数量">${leftKey}</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="剩余key数量">0</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkAlienwarearena = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- let userCountry = response.responseText.match(/user_country.*?=.*?"([\w]+)"/);
- userCountry = userCountry ? userCountry[1] : '';
- let prestigeLevel = response.responseText.match(/prestige_level.*?=.*?([\d]+)/);
- prestigeLevel = prestigeLevel ? parseInt(prestigeLevel[1], 10) : 0;
- let fullLevel = response.responseText.match(/full_level.*?=.*?([\d]+)/);
- fullLevel = fullLevel ? parseInt(fullLevel[1], 10) : 0;
- let countryKeys = response.responseText.match(/countryKeys.*?=.*?(\{.+\});/);
- if (countryKeys) {
- countryKeys = JSON.parse(countryKeys[1]);
- } else {
- return;
- }
- const keyType = prestigeLevel ? 'prestige' : 'normal';
- let userCountryKeys = countryKeys[userCountry][keyType];
- let lowestLevelWithKeys;
- let highestKeysForUser;
- let keysForUser = false;
- for (const level in userCountryKeys) {
- if (userCountryKeys[level] > 0) {
- if (!lowestLevelWithKeys) { lowestLevelWithKeys = level; }
- if (fullLevel >= level) {
- if (!highestKeysForUser || userCountryKeys[level] > highestKeysForUser) { highestKeysForUser = userCountryKeys[level]; }
- }
- }
- }
- if (!highestKeysForUser && keyType === 'prestige') {
- userCountryKeys = countryKeys[userCountry].normal;
- for (const level in userCountryKeys) {
- if (userCountryKeys[level] > 0) {
- if (!lowestLevelWithKeys) { lowestLevelWithKeys = level; }
- if (fullLevel >= level) {
- if (!highestKeysForUser || userCountryKeys[level] > highestKeysForUser) { highestKeysForUser = userCountryKeys[level]; }
- }
- }
- }
- }
- if (highestKeysForUser) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(highestKeysForUser)}" title="剩余key数量">${highestKeysForUser}</font>`);
- keysForUser = true;
- }
- if (!keysForUser) {
- if (lowestLevelWithKeys) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-red" title="等级不足">等级不足</font>');
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-red" title="剩余key数量">0</font>');
- }
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkItch = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('.promotion_dates .date_format');
- if (counter.length > 0) {
- const endTime = `${counter.attr('title').trim()}Z`;
- const time = getTime(endTime);
- if (time !== 0) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font data-time="${endTime}" class="left-keys ${time.class}" title="剩余时间">${time.time}</font>`);
- setInterval(() => {
- const leftTimeEle = $(`font[data-time="${endTime}"]`);
- const leftTime = getTime(endTime);
- if (leftTime !== 0) {
- if (!leftTimeEle.hasClass(leftTime.class)) leftTimeEle.attr('class', `left-keys ${leftTime.class}`);
- leftTimeEle.text(leftTime.time);
- } else {
- leftTimeEle.attr('class', 'left-keys lk-red').attr('title', '活动已结束')
- .text('end');
- }
- }, 500);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-red" title="活动已结束">end</font>');
- }
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-red" title="活动已结束">end</font>');
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkGiveawaysu = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('div.giveaway-ended');
- if (counter.length > 0) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="已结束">End</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(100)}" title="进行中">Active</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkGivekey = (url, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- const counter = $(`<div>${response.responseText}</div>`).find('#keys_count');
- if (counter.length > 0) {
- const [leftKey] = counter.text().trim()
- .match(/[\d]+/);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(leftKey)}" title="剩余key数量">${leftKey}</font>`);
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="剩余key数量">0</font>`);
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const checkCubejoy = (gameId, e) => {
- GM_xmlhttpRequest({
- method: 'get',
- url: `https://store.cubejoy.com/html/en/store/goodsdetail/detail${gameId}.html`,
- timeout: 30 * 1000,
- ontimeout: () => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求超时">timeout</font>');
- },
- onerror: (err) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="请求失败">error</font>');
- console.error(err);
- },
- onload: (response) => {
- const thisEle = $(`a[href="${$(e).attr('href')}"]`);
- try {
- let price = response.responseText.match(/<span class="gameoriginal">[\D]*?([\d.]+)/)?.[1] || '';
- if (!price && response.responseText.includes('免费游戏</span>')) {
- price = '0';
- }
- if (/^[\d.]+$/.test(price)) {
- price = parseInt(price, 10);
- if (price === 0) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(100)}" title="游戏价格">¥ 0.00</font>`);
- } else if (price > 0) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after(`<font class="left-keys ${getClass(0)}" title="游戏价格">¥ ${price / 100}</font>`);
- }
- } else {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取游戏价格失败">error</font>');
- }
- } catch (err) {
- if (!thisEle.next().hasClass('left-keys')) thisEle.after('<font class="left-keys lk-black" title="获取数据失败">error</font>');
- console.error(err);
- }
- }
- });
- };
- const leftTitle = $('.subforum_left_title_left_up a').eq(3);
- const leftTitleHref = leftTitle.length > 0 ? leftTitle.attr('href') : '';
- if ((leftTitleHref.includes('f319-1') || (leftTitleHref.includes('page=1') && leftTitleHref.includes('fid=319'))) && leftTitle.text() === '福利放送') {
- const marvelousgaLinks = $('a[href*="marvelousga.com/giveaway/"]');
- const grabfreegameLinks = $('a[href*="grabfreegame.com/giveaway/"],a[href*="bananagiveaway.com/giveaway/"]');
- const gamehagLinks = $('a[href*="gamehag.com/giveaway/"]');
- const prysLinks = $('a[href*="prys.revadike.com/giveaway/?id="]');
- const takekeyLinks = $('a[href*="takekey.ru/distribution/"]');
- const alienwarearenaLinks = $('a[href*="alienwarearena.com/ucf/show/"]');
- const itchLinks = $('a[href*="itch.io/s/"]');
- const giveawaysuLinks = $('a[href*="giveaway.su/giveaway/view/"]');
- const givekeyLinks = $('a[href*="givekey.ru/giveaway/"]');
- const cubejoyLinks = $('a[href*="store.cubejoy.com/html/en/store/goodsdetail/detail"],a[href*="cart.cubejoy.com/shop/xnEdition.html?pid="]');
- if (marvelousgaLinks.length > 0) {
- for (const e of marvelousgaLinks) {
- const test = $(e).attr('href')
- .match(/https?:\/\/marvelousga\.com\/giveaway\/(.+)/);
- const id = test ? test[1] : false;
- if (id) checkMarvelousga(id, e);
- }
- }
- if (grabfreegameLinks.length > 0) {
- for (const e of grabfreegameLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/www\.(grabfreegame|bananagiveaway)\.com\/giveaway\/.*/.test(link)) checkGrabfreegame(link, e);
- }
- }
- if (gamehagLinks.length > 0) {
- for (const e of gamehagLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/.*?gamehag\.com\/giveaway\/[\d]+.*?/.test(link)) checkGamehag(link, e);
- }
- }
- if (prysLinks.length > 0) {
- for (const e of prysLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/prys\.revadike\.com\/giveaway\/\?id=[\d]+/.test(link)) checkPrys(link, e);
- }
- }
- if (takekeyLinks.length > 0) {
- for (const e of takekeyLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/takekey\.ru\/distribution\/[\d]+/.test(link)) checkTakekey(link, e);
- }
- }
- if (alienwarearenaLinks.length > 0) {
- for (const e of alienwarearenaLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/.*?\.alienwarearena\.com\/ucf\/show\/[\d]+.*?/.test(link)) checkAlienwarearena(link, e);
- }
- }
- if (itchLinks.length > 0) {
- for (const e of itchLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/itch\.io\/s\/[\d]+?\/.*/.test(link)) checkItch(link, e);
- }
- }
- if (giveawaysuLinks.length > 0) {
- for (const e of giveawaysuLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/giveaway\.su\/giveaway\/view\/[\d]+/.test(link)) checkGiveawaysu(link, e);
- }
- }
- if (givekeyLinks.length > 0) {
- for (const e of givekeyLinks) {
- const link = $(e).attr('href');
- if (/^https?:\/\/givekey\.ru\/giveaway\/[\d]+/.test(link)) checkGivekey(link, e);
- }
- }
- if (cubejoyLinks.length > 0) {
- for (const e of cubejoyLinks) {
- const link = $(e).attr('href');
- const gameId = link.match(/goodsdetail\/detail([\d]+?)\.html/) || link.match(/xnEdition\.html\?pid=([\d]+)/);
- if (gameId && gameId[1]) checkCubejoy(gameId[1], e);
- }
- }
- }
- GM_addStyle(`
- .left-keys{
- color: #fff;
- border-radius: 10px;
- padding: 0 5px;
- margin-left: 5px;
- }
- .lk-green{
- background-color: #5cb85c;
- }
- .lk-yellow{
- background-color: #f0ad4e;
- }
- .lk-red{
- background-color: #d9534f;
- }
- .lk-black{
- background-color: #000;
- }
- `);
- }());