Instantly share code, notes, and snippets.
Last active
May 21, 2024 21:58
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Kurotaku-sama/2f22a38c553d5403a97271edaa601b8f to your computer and use it in GitHub Desktop.
Adds buttons to send commands for the onstream games in the YouTube chat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name YouTube hitsquadgodfather command buttons | |
// @namespace kurotaku.de | |
// @version 1.2.6 | |
// @description Adds buttons to send commands for the onstream games in the YouTube chat | |
// @author Kurotaku | |
// @license MIT | |
// @match https://www.youtube.com/live_chat?* | |
// @icon https://www.youtube.com/s/desktop/6ee70b2c/img/favicon_32x32.png | |
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js | |
// @updateURL https://gist.github.com/Kurotaku-sama/2f22a38c553d5403a97271edaa601b8f/raw/YouTube%2520hitsquadgodfather%2520command%2520buttons.user.js | |
// @downloadURL https://gist.github.com/Kurotaku-sama/2f22a38c553d5403a97271edaa601b8f/raw/YouTube%2520hitsquadgodfather%2520command%2520buttons.user.js | |
// @require https://gist.github.com/Kurotaku-sama/9ebeb659500f6eee2f780344948e1e8f/raw/kuros_library.user.js | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @grant GM_registerMenuCommand | |
// ==/UserScript== | |
(async function() { | |
if(document.querySelector("html").innerHTML.includes("HitsquadGodfather")) { // Check if the page contains the word HitsquadGodfather to make sure its only appearing on GF Stream | |
await init_gm_config(); // Initialize the configuration | |
wait_for_element('#input-container #input.yt-live-chat-text-input-field-renderer').then(async () => { | |
let buttongroups = ""; | |
if(GM_config.get("buttons_general")) | |
buttongroups += `<label class="k-buttongroup-label">General</label> | |
<div class="k-buttongroup"> | |
<button cmd="hitsquad" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Hitsquad</button> | |
<button cmd="strikes" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Strikes</button> | |
<button cmd="points" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Points</button> | |
</div></div>`; | |
if(GM_config.get("buttons_trivia")) | |
buttongroups += `<label class="k-buttongroup-label">Trivia</label> | |
<div class="k-buttongroup"> | |
<button cmd="answer1" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">1</button> | |
<button cmd="answer2" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">2</button> | |
<button cmd="answer3" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">3</button> | |
<button cmd="answer4" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">4</button> | |
</div>`; | |
if(GM_config.get("showdown_buttons")) { | |
buttongroups += ``; | |
// Selection | |
buttongroups += `<label class="k-buttongroup-label">Showdown</label> | |
<div class="k-buttongroup"> | |
<button cmd="wizard" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Wizard</button> | |
<button cmd="knight" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Knight</button> | |
<button cmd="cleric" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Cleric</button> | |
<button cmd="experience" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Experience</button> | |
</div>`; | |
// Labels to show roles | |
buttongroups += `<div class="k-labelgroup"> | |
<label class="k-selection-label" data-role="wizard">Wizard</label> | |
<label class="k-selection-label" data-role="knight">Knight</label> | |
<label class="k-selection-label" data-role="cleric">Cleric</label> | |
<label class="k-selection-label" data-role="close">Close</label> | |
</div>`; | |
// Wizard | |
buttongroups += `<div class="k-buttongroup k-role hidden" data-role="wizard"> | |
<button cmd="attack" class="targetbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Attack</button> | |
<button cmd="flames" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Flames</button> | |
<button cmd="shield" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Shield</button> | |
<button cmd="moan" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Moan</button> | |
</div>`; | |
// Knight | |
buttongroups += `<div class="k-buttongroup k-role hidden" data-role="knight"> | |
<button cmd="attack" class="targetbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Attack</button> | |
<button cmd="frenzy" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Frenzy</button> | |
<button cmd="rally" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Rally</button> | |
<button cmd="moan" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Moan</button> | |
</div>`; | |
// Cleric | |
buttongroups += `<div class="k-buttongroup k-role hidden" data-role="cleric"> | |
<button cmd="attack" class="targetbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Attack</button> | |
<button cmd="divine" class="targetbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Divine</button> | |
<button cmd="heal" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Heal</button> | |
<button cmd="moan" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Moan</button> | |
</div>`; | |
} | |
let html = `<div id="actions" class="k-buttongroups">${buttongroups}</div>`; | |
html += `<div id="targets" class="k-buttongroups hidden" data-action=""> | |
<label class="k-buttongroup-label targets">Targets</label> | |
<div class="k-buttongroup"> | |
<button cmd="1" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">1</button> | |
<button cmd="2" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">2</button> | |
<button cmd="3" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">3</button> | |
<button cmd="4" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">4</button> | |
<button cmd="5" class="actionbutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">5</button> | |
<button class="closebutton yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m">Close</button> | |
</div>`; | |
document.querySelector("#contents #panel-pages").insertAdjacentHTML('beforebegin', html); | |
if(document.querySelector(".k-buttongroup .closebutton")) | |
document.querySelector(".k-buttongroup .closebutton").addEventListener("click", close_target, false); | |
let actionbuttons = document.querySelectorAll(".k-buttongroup .actionbutton"); | |
actionbuttons.forEach(el => {el.addEventListener("click", send_command, false)}); | |
let targetbuttons = document.querySelectorAll(".k-buttongroup .targetbutton"); | |
targetbuttons.forEach(el => {el.addEventListener("click", switch_panel, false)}); | |
let selection_labels = document.querySelectorAll(".k-selection-label"); | |
selection_labels.forEach(el => {el.addEventListener("click", show_role, false)}); | |
}); | |
} | |
})(); | |
function init_gm_config() { | |
GM_registerMenuCommand('Settings', () => { | |
GM_config.open(); | |
}); | |
let frame = document.createElement('div'); | |
document.body.appendChild(frame); | |
GM_config.init( | |
{ | |
'id': 'configuration', | |
'title': 'YouTube hitsquadgodfather config', | |
'fields': | |
{ | |
'script_enabled': | |
{ | |
'label': 'Enable/Disable the script', | |
'type': 'checkbox', | |
'default': true | |
}, | |
'buttons_general': | |
{ | |
'label': 'General buttons', | |
'type': 'checkbox', | |
'default': true | |
}, | |
'buttons_trivia': | |
{ | |
'label': 'Trivia buttons', | |
'type': 'checkbox', | |
'default': true | |
}, | |
'showdown_buttons': { | |
'label': 'Showdown buttons', | |
'type': 'checkbox', | |
'default': true | |
}, | |
}, | |
'events': { | |
'save': () => {location.reload()}, | |
}, | |
'frame': frame, | |
'css': '#configuration {color: black; height:auto !important; width:auto !important; padding:20px !important;max-height: 600px !important;max-width:500px !important; border: 3px solid #000 !important} #configuration .section_header {background: unset; color:unset;} #configuration .config_header {font-size:17pt; font-weight:bold} #configuration .config_var {margin-top:10px; display: flex;} .config_var :nth-child(2) {order:-1; margin-right:10px;} #configuration_buttons_holder {text-align: center;} #configuration #configuration_resetLink {color:#fff;}' | |
}); | |
} | |
function close_target() { | |
switch_panel(null); | |
} | |
function switch_panel(event) { | |
document.querySelector("#actions").classList.toggle("hidden"); | |
document.querySelector("#targets").classList.toggle("hidden"); | |
if(event) | |
document.querySelector("#targets").setAttribute("data-action", event.target.getAttribute("cmd")); | |
} | |
function show_role(event) { | |
let roles = document.querySelectorAll(".k-role"); | |
roles.forEach(el => { | |
if(el.getAttribute("data-role") === event.target.getAttribute("data-role")) | |
el.classList.remove("hidden") | |
else | |
el.classList.add("hidden") | |
}); | |
} | |
function send_command(event) { | |
let cmd = ""; | |
if(event.target.parentNode.parentNode.getAttribute("data-action")) { | |
cmd = event.target.parentNode.parentNode.getAttribute("data-action"); // Add action attack or devine in case its from the switched panel | |
// Remove the data and go back to main panel | |
event.target.parentNode.parentNode.setAttribute("data-action", ""); | |
switch_panel(null); | |
} | |
cmd += event.target.getAttribute("cmd"); | |
let suffix = "!"; | |
if(cmd.trim() !== "" && cmd !== null) | |
sendMessageToYouTubeChat(suffix + cmd + ' - ' + makeid(5)); | |
//console.log(suffix + cmd); | |
else | |
alert("Please contact script creator, this button doesn't seem to work correctly"); | |
} | |
function sendMessageToYouTubeChat(message) { | |
// Without this solution I probably would hang myself :D | |
// https://stackoverflow.com/questions/75962593/sending-message-on-youtube-live-chat-with-chrome-extension | |
console.log('Sending message:', message); | |
//const liveChatFrame = document.querySelector('iframe.style-scope.ytd-live-chat-frame'); | |
//const chatInputBox = liveChatFrame.contentDocument.querySelector('#input.yt-live-chat-text-input-field-renderer'); | |
const chatInputBox = document.querySelector('#input.yt-live-chat-text-input-field-renderer'); | |
console.log('Chat input box:', chatInputBox); | |
chatInputBox.focus(); | |
chatInputBox.innerText = message; | |
chatInputBox.dispatchEvent(new Event('input', { bubbles: true })); | |
//setTimeout(() => { | |
//const sendButton = liveChatFrame.contentDocument.querySelector('#button.yt-icon-button[aria-label="Send"]'); | |
const sendButton = document.querySelector('#send-button button'); | |
console.log('Send button:', sendButton); | |
if (sendButton) { | |
console.log('Clicking send button'); | |
try { | |
sendButton.dispatchEvent(new MouseEvent('click', { bubbles: true })); | |
} catch (error) { | |
console.error('Error sending message:', error); | |
} | |
} else { | |
console.error('Could not find send button'); | |
} | |
//}, 1000); | |
} | |
// Add custom styles | |
let styles = ` | |
.k-buttongroups { | |
padding-left: 20px; | |
padding-right: 20px;} | |
.k-buttongroup { | |
display: flex; | |
flex-wrap: wrap; | |
grid-column-gap: 10px;} | |
.k-buttongroup-label {} | |
.k-buttongroup > button { | |
min-width:50px; | |
margin-bottom:5px;} | |
.k-labelgroup { | |
margin-top: 10px; | |
font-size: 20px; | |
justify-content: space-between; | |
display: flex;} | |
.hidden { display:none;} | |
`; | |
// Insert custom Styles | |
let style_sheet = document.createElement("style"); | |
style_sheet.innerText = styles; | |
document.head.appendChild(style_sheet); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment