Skip to content

Instantly share code, notes, and snippets.

@nullptrerror
Created September 17, 2024 18:05
Show Gist options
  • Save nullptrerror/0b1f557dfcedaa6bfec191c0598d3948 to your computer and use it in GitHub Desktop.
Save nullptrerror/0b1f557dfcedaa6bfec191c0598d3948 to your computer and use it in GitHub Desktop.
Realm Status Javascript Checker
(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