// ==UserScript==
// @name bilibili直播自定义皮肤背景
// @namespace http://tampermonkey.net/
// @version 2.0.1
// @description 自定义bilibili直播的皮肤和背景,仅自己可见!
// @author HCLonely
// @include /^https?:\/\/live.bilibili.com\/(blanc\/)?[\d]+/
// @run-at document-end
// @connect api.live.bilibili.com
// @connect *
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @require https://cdn.jsdelivr.net/npm/jquery@3.4.0/dist/jquery.min.js
// @homepage https://blog.hclonely.com/posts/578f9be7/
// @supportURL https://blog.hclonely.com/posts/578f9be7/
// @downloadURL none
// ==/UserScript==
(function () {
'use strict';
const skinConfig = GM_getValue('skinConfig') || [{ id: 0, skin_name: '默认' }]
let selectedSkin = GM_getValue('selectedSkin') || 0
let customedBgimg = GM_getValue('customedBgimg') || 0
if (selectedSkin !== 0 && skinConfig[selectedSkin]) {
generateStyle(skinConfig[selectedSkin].skin_config)
}
if (customedBgimg) {
changeBackgroundImage(customedBgimg)
}
const init = setInterval(() => {
if ($('.icon-left-part').length > 0) {
clearInterval(init)
$('.icon-left-part').after(``)
$('.skin-custom').click(() => {
if ($('#skin-setting-div').length > 0) {
$('#skin-setting-div').hide('fast', () => { $('#skin-setting-div').remove() })
} else {
let html = ''
for (const config of skinConfig) {
html += `
`
}
$('#control-panel-ctnr-box').append(`
`)
$('#skin-setting-div').show('normal')
$("input.background-custom").bind('input porpertychange', function () {
if ($(this).val().length > 0) {
$('button.change-bgimg').removeAttr('disabled')
} else {
$('button.change-bgimg').attr('disabled', 'disabled')
}
})
$('button.change-bgimg').click(function () {
customedBgimg = $("input.background-custom").val()
if (customedBgimg === '0'){
customedBgimg = 0
}else{
changeBackgroundImage(customedBgimg)
}
GM_setValue('customedBgimg', customedBgimg)
})
$('#skin-setting-div .item').click(function (e) {
if (e.target === $(this).find('input')[0]) {
$('#skin-setting-div .item>span.svg-icon').removeClass('checkbox-selected').addClass('checkbox-default')
$(this).find('span.svg-icon').removeClass('checkbox-default').addClass('checkbox-selected')
selectedSkin = parseInt($(this).attr('data-id'))
if (selectedSkin !== 0) {
generateStyle(skinConfig[selectedSkin].skin_config)
}
GM_setValue('selectedSkin', selectedSkin)
}
})
}
})
$(document).on('click', function (e) {
const skinSettingDiv = $('#skin-setting-div')
const skinSettingIcon = $('#skin-setting-icon')
if (!skinSettingDiv.is(e.target) && skinSettingDiv.has(e.target).length === 0 && !skinSettingIcon.is(e.target) && skinSettingIcon.has(e.target).length === 0) {
skinSettingDiv.hide('fast', () => { skinSettingDiv.remove() })
}
});
updateSkinConfig(skinConfig.length)
}
})
function updateSkinConfig(id) {
GM_xmlhttpRequest({
url: `https://api.live.bilibili.com/room/v1/Skin/info?skin_platform=web&skin_version=1&id=${id}`,
methon: 'get',
responseType: 'json',
onload: data => {
if (data.response.code === 0 && !Array.isArray(data.response.data)) {
const skinData = data.response.data
skinData.skin_config = JSON.parse(skinData.skin_config)
skinConfig[skinData.id] = skinData
GM_setValue('skinConfig', skinConfig)
$('#skin-setting-div .list').append(`
`)
updateSkinConfig(++id)
}
}
})
}
function changeBackgroundImage(url) {
GM_xmlhttpRequest({
url: url,
methon: 'get',
responseType: 'blob',
onload: data => {
if(data.status === 200){
$('[role="img.webp"]').css('background-image', 'url(' + window.URL.createObjectURL(data.response) + ')')
} else {
$('[role="img.webp"]').css('background-image', 'url(' + url + ')')
}
},
onerror: () => {
$('[role="img.webp"]').css('background-image', 'url(' + url + ')')
}
})
}
function generateStyle(skinConfig) {
const mainText = skinConfig.mainText.replace(/#([\d\w]{2})(.+)/, function (match, p1, p2) {
return '#' + p2 + p1
})
const normalText = skinConfig.normalText.replace(/#([\d\w]{2})(.+)/, function (match, p1, p2) {
return '#' + p2 + p1
})
const highlightContent = skinConfig.highlightContent.replace(/#([\d\w]{2})(.+)/, function (match, p1, p2) {
return '#' + p2 + p1
})
const highlightContentHover = skinConfig.highlightContent.replace(/#([\d\w]{2})(.+)/, function (match, p1, p2) {
return '#' + p2 + 'cc'
})
const border = skinConfig.border.replace(/#([\d\w]{2})(.+)/, function (match, p1, p2) {
return '#' + p2 + p1
})
const skinCss = `
.live-skin-coloration-area .live-skin-main-text {
color: ${mainText} !important;
fill: ${mainText} !important;
}
.live-skin-coloration-area .live-skin-main-a-text:link,.live-skin-coloration-area .live-skin-main-a-text:visited {
color: ${mainText} !important;
}
.live-skin-coloration-area .week-icon {
color: ${mainText} !important;
border-color: ${mainText} !important;
}
.live-skin-coloration-area .live-skin-main-a-text:hover,.live-skin-coloration-area .live-skin-main-a-text:active {
color: ${mainText} !important;
}
.live-skin-coloration-area .live-skin-normal-text {
color: ${normalText} !important;
}
.live-skin-coloration-area .live-skin-normal-a-text {
color: ${normalText} !important;
}
.live-skin-coloration-area .live-skin-normal-a-text:link,.live-skin-coloration-area .live-skin-normal-a-text:visited {
color: ${normalText} !important;
}
.live-skin-coloration-area .live-skin-normal-a-text:hover,.live-skin-coloration-area .live-skin-normal-a-text:active {
color: ${highlightContent} !important;
}
.live-skin-coloration-area .live-skin-highlight-text {
color: ${highlightContent} !important;
}
.live-skin-coloration-area .live-skin-highlight-bg {
background-color: ${highlightContent} !important;
}
.live-skin-coloration-area .live-skin-highlight-border {
border-color: ${highlightContent} !important;
}
.live-skin-coloration-area .live-skin-highlight-button-bg.bl-button--primary:not(:disabled) {
background-color: ${highlightContent};
}
.live-skin-coloration-area .live-skin-highlight-button-bg.bl-button--primary:hover:not(:disabled) {
background-color: ${highlightContentHover};
}
.live-skin-coloration-area .live-skin-highlight-button-bg.bl-button--primary:active:not(:disabled) {
background-color: ${highlightContentHover};
}
.live-skin-coloration-area .live-skin-separate-border {
border-color: ${border} !important;
}
.live-skin-coloration-area .live-skin-separate-area {
background-color: ${border} !important;
}
.live-skin-coloration-area .live-skin-separate-area-hover:hover {
background-color: ${border} !important;
}
.live-skin-coloration-area .live-skin-button-text:not(:disabled) {
color: rgba(255,255,255,1);
fill: rgba(255,255,255,1);
}
#head-info-vm {
background-image: url("${skinConfig.headInfoBgPic}");
}
#gift-control-vm {
background-image: url("${skinConfig.giftControlBgPic}");
}
#rank-list-vm,#rank-list-ctnr-box {
background-image: url("${skinConfig.rankListBgPic}");
}
#chat-control-panel-vm {
background-image: url("${skinConfig.rankListBgPic}");
}
.supportWebp #head-info-vm {
background-image: url("${skinConfig.headInfoBgPic}@90q.webp");
}
.supportWebp #gift-control-vm {
background-image: url("${skinConfig.giftControlBgPic}@90q.webp");
}
.supportWebp #rank-list-vm,.supportWebp #rank-list-ctnr-box {
background-image: url("${skinConfig.rankListBgPic}@90q.webp");
}
.supportWebp #chat-control-panel-vm {
background-image: url("${skinConfig.rankListBgPic}@90q.webp");
}
#head-info-vm,#gift-control-vm {
border: none !important;
padding: 1px;
}
#aside-area-vm {
border: none !important;
}
#rank-list-vm,#rank-list-ctnr-box {
background-repeat: no-repeat;
background-size: 100% auto;
}
#chat-control-panel-vm {
background-repeat: no-repeat;
background-size: 100% auto;
background-position: bottom left;
}
`
GM_addStyle(skinCss)
}
})();