Created
September 17, 2024 18:05
-
-
Save nullptrerror/0b1f557dfcedaa6bfec191c0598d3948 to your computer and use it in GitHub Desktop.
Realm Status Javascript Checker
This file contains hidden or 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
(function () { | |
// Create and return the audio element and its container | |
const createAudioElement = () => { | |
const audioContainer = document.createElement('div'); | |
audioContainer.style.textAlign = 'center'; | |
audioContainer.style.marginBottom = '20px'; | |
// Create the status text element | |
const statusText = document.createElement('div'); | |
statusText.className = 'font-semp-xLarge-white'; | |
statusText.style.fontSize = '24px'; // Set a default font size | |
statusText.style.color = '#db2300'; // Default to offline (red) | |
statusText.textContent = 'Proudmoore Offline'; // Default text | |
audioContainer.appendChild(statusText); | |
// Create the audio element | |
const audioElement = document.createElement('audio'); | |
audioElement.controls = true; | |
audioElement.loop = true; | |
audioElement.id = 'realmAudio'; | |
// Apply styles to the audio element itself | |
audioElement.style.backgroundColor = '#333'; // Change background color to dark gray | |
audioElement.style.color = '#fff'; // Change text color to white | |
audioElement.style.width = '300px'; // Set width of the audio player | |
audioElement.style.padding = '10px'; // Add padding to the audio element | |
audioElement.style.borderRadius = '10px'; // Add rounded corners | |
audioContainer.appendChild(audioElement); | |
// Insert the audio container above the specified element | |
const referenceElement = document.querySelector( | |
"#realm-status-mount > div > div.Pane-content > div.margin-bottom-normal > div.flex-items-end.margin-bottom-normal.contain-large.padding-bottom-normal > div.margin-bottom-normal.Grid--center" | |
); | |
if (referenceElement) { | |
referenceElement.parentNode.insertBefore(audioContainer, referenceElement); | |
} | |
return { audioElement, statusText }; | |
}; | |
// Set the background color of the audio player and update the status text based on server status (green for online, red for offline) | |
const updatePlayerStatus = (audioElement, statusText, isOnline) => { | |
if (isOnline) { | |
audioElement.style.backgroundColor = '#1b9601'; // Green background for online | |
statusText.style.color = '#1b9601'; // Green text for online | |
statusText.textContent = 'Proudmoore Online'; // Change text to "Proudmoore Online" | |
} else { | |
audioElement.style.backgroundColor = '#db2300'; // Red background for offline | |
statusText.style.color = '#db2300'; // Red text for offline | |
statusText.textContent = 'Proudmoore Offline'; // Change text to "Proudmoore Offline" | |
} | |
}; | |
// Play the already fetched and decompressed audio without re-downloading | |
const playAudio = (audioElement, audioUrl) => { | |
if (!audioElement.src || audioElement.src !== audioUrl) { | |
audioElement.src = audioUrl; // Set or update the audio source | |
} | |
audioElement.play(); // Play the audio | |
}; | |
// Stop the audio without clearing its source | |
const stopAudio = (audioElement) => { | |
audioElement.pause(); // Pause the audio but keep the source | |
}; | |
// Simulate interaction by setting input and clicking buttons | |
const simulateInteraction = () => { | |
// Set the input value to "Proudmoore" if it's not already set | |
const inputField = document.querySelector( | |
"#realm-status-mount > div > div.Pane-content > div.margin-bottom-normal > div.flex-items-end.margin-bottom-normal.contain-large.padding-bottom-normal > div.flex.flex-items-end > div:nth-child(3) > div.SearchInputField.SearchInputField--black.SearchInputField--small > input" | |
); | |
if (inputField && inputField.value !== "Proudmoore") { | |
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set; | |
nativeInputValueSetter.call(inputField, "Proudmoore"); | |
inputField.dispatchEvent(new Event("input", { bubbles: true, cancelable: true })); | |
} | |
// Click button 2 (World of Warcraft Classic) | |
const wowClassicButton = document.querySelector( | |
"#realm-status-mount > div > div.Pane-content > div.margin-bottom-normal > div.flex-items-end.margin-bottom-normal.contain-large.padding-bottom-normal > div.margin-bottom-normal.Grid--center > div > div > div > button:nth-child(2)" | |
); | |
if (wowClassicButton) { | |
wowClassicButton.click(); // Simulate click on WoW Classic button | |
} | |
// Click button 1 (World of Warcraft) | |
const wowButton = document.querySelector( | |
"#realm-status-mount > div > div.Pane-content > div.margin-bottom-normal > div.flex-items-end.margin-bottom-normal.contain-large.padding-bottom-normal > div.margin-bottom-normal.Grid--center > div > div > div > button:nth-child(1)" | |
); | |
if (wowButton) { | |
setTimeout(() => wowButton.click(), 500); // Simulate click on WoW button after 500ms | |
} | |
}; | |
// Function to check the online status of Proudmoore and control the audio element | |
const checkProudmooreStatus = async (audioElement, statusText, audioUrl) => { | |
// Simulate interactions (set input to Proudmoore and click buttons) | |
simulateInteraction(); | |
const query = { | |
operationName: "GetRealmStatusData", | |
variables: { | |
input: { | |
compoundRegionGameVersionSlug: "us" | |
} | |
}, | |
extensions: { | |
persistedQuery: { | |
version: 1, | |
sha256Hash: "b37e546366a58e211e922b8c96cd1ff74249f564a49029cc9737fef3300ff175" | |
} | |
} | |
}; | |
try { | |
const response = await fetch("https://worldofwarcraft.blizzard.com/graphql", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json" | |
}, | |
body: JSON.stringify(query) | |
}); | |
const data = await response.json(); | |
const proudmoore = data.data.Realms.find(realm => realm.slug === "proudmoore"); | |
if ((proudmoore && proudmoore.online === true) || window.testOnline === true) { | |
console.log("Proudmoore is online. Playing song..."); | |
updatePlayerStatus(audioElement, statusText, true); // Update status to online | |
playAudio(audioElement, audioUrl); // Play the audio | |
} else { | |
console.log("Proudmoore is currently offline."); | |
updatePlayerStatus(audioElement, statusText, false); // Update status to offline | |
stopAudio(audioElement); // Pause the audio without removing the source | |
} | |
} catch (error) { | |
console.error("Error fetching the realm status:", error); | |
updatePlayerStatus(audioElement, statusText, false); // Set to offline on error | |
stopAudio(audioElement); // Pause the audio on error | |
} | |
// Schedule the next check with a random delay between 1-10 seconds | |
const delay = Math.floor(Math.random() * (10000 - 1000 + 1) + 1000); | |
console.log(`Next check in ${delay / 1000} seconds...`); | |
setTimeout(() => checkProudmooreStatus(audioElement, statusText, audioUrl), delay); | |
}; | |
// Function to decode the Base64 string to a Uint8Array | |
const base64ToUint8Array = (base64) => { | |
const binaryString = atob(base64); | |
const len = binaryString.length; | |
const bytes = new Uint8Array(len); | |
for (let i = 0; i < len; i++) { | |
bytes[i] = binaryString.charCodeAt(i); | |
} | |
return bytes; | |
}; | |
// Function to decompress the Gzipped MP3 file using DecompressionStream | |
const decompressGzip = async (compressedData) => { | |
const stream = new Response(compressedData).body | |
.pipeThrough(new DecompressionStream('gzip')); | |
const decompressedChunks = []; | |
const reader = stream.getReader(); | |
while (true) { | |
const { done, value } = await reader.read(); | |
if (done) break; | |
decompressedChunks.push(value); | |
} | |
// Concatenate all chunks into a single Uint8Array | |
let totalLength = 0; | |
decompressedChunks.forEach(chunk => totalLength += chunk.length); | |
const decompressedArray = new Uint8Array(totalLength); | |
let offset = 0; | |
decompressedChunks.forEach(chunk => { | |
decompressedArray.set(chunk, offset); | |
offset += chunk.length; | |
}); | |
return decompressedArray; | |
}; | |
// IIFE to initialize everything and avoid polluting the global scope | |
(async function initialize() { | |
// Create the audio element and status text | |
const { audioElement, statusText } = createAudioElement(); | |
// Fetch the Base64-encoded Gzipped MP3 file | |
const gistUrl = 'https://gist.githubusercontent.com/nullptrerror/938104fc4b9fa0c1d73bf4616fd3b57d/raw/f2cf7823acea571e106b5ce09acbf65d6b60a342/aerosmith_dream_on.mp3.txt'; | |
try { | |
const response = await fetch(gistUrl); | |
const base64String = await response.text(); // Get Base64-encoded string | |
// Convert the Base64 string to a Uint8Array (binary data) | |
const compressedData = base64ToUint8Array(base64String); | |
// Decompress the Gzipped binary data | |
const decompressedData = await decompressGzip(compressedData); | |
// Create a Blob from the decompressed data and generate an object URL | |
const blob = new Blob([decompressedData], { type: 'audio/mp3' }); | |
const audioUrl = URL.createObjectURL(blob); // Create object URL from Blob | |
// Start checking the server status and controlling the audio | |
checkProudmooreStatus(audioElement, statusText, audioUrl); | |
} catch (error) { | |
console.error('Error fetching or decompressing the song:', error); | |
} | |
})(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment