Roblox Multi-Feature User Panel.

Download Roblox thumbnails, game info, badge info, and user info and the images for all those!

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         Roblox Multi-Feature User Panel.
// @namespace    http://tampermonkey.net/
// @version      1.7
// @description  Download Roblox thumbnails, game info, badge info, and user info and the images for all those!
// @author       NotRoblox
// @match        https://www.roblox.com/userpanel
// @match        https://www.roblox.com/getgameinfo
// @match        https://www.roblox.com/getbadgeinfo
// @match        https://www.roblox.com/getuserinfo
// @match        https://www.roblox.com/getgroupinfo
// @grant        GM_cookie
// @connect      promocodes.roblox.com
// @connect      auth.roblox.com
// @connect      www.roblox.com
// @match        https://www.roblox.com/*
// @match        https://promocodes.roblox.com/*
// @match        https://auth.roblox.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// @grant        GM_download
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    const style = document.createElement('style');
    style.textContent = `
    /* Only apply styles to our custom pages */
    body.custom-roblox-tool {
        background-color: #f4f7f6 !important;
        overflow-x: hidden;
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
    }

    /* Only hide error elements on our custom pages */
    body.custom-roblox-tool .content,
    body.custom-roblox-tool .request-error-page-content,
    body.custom-roblox-tool .default-error-page,
    body.custom-roblox-tool .message-container,
    body.custom-roblox-tool .error-title,
    body.custom-roblox-tool .error-message,
    body.custom-roblox-tool .error-image,
    body.custom-roblox-tool .action-buttons,
    body.custom-roblox-tool #container-main,
    body.custom-roblox-tool .error-message-container {
        display: none !important;
    }

    /* Rest of your component styles remain the same, but prefix with body.custom-roblox-tool */
    body.custom-roblox-tool .main-content-wrapper {
        width: 100%;
        padding: 20px;
        margin-top: 60px;
        margin-bottom: 120px;
        display: flex;
        flex-direction: column;
        align-items: center;
        min-height: calc(100vh - 200px);
    }

        body {
            background-color: #f4f7f6 !important;
            overflow-x: hidden;
        }

        body {
            font-family: Arial, sans-serif;
            background-color: #f4f7f6;
            margin: 0;
            padding: 0;
        }

    .main-content-wrapper {
        width: 100%;
        padding: 20px;
        margin-top: 60px; /* Add this line to create space at the top */
        margin-bottom: 120px;
        display: flex;
        flex-direction: column;
        align-items: center;
        min-height: calc(100vh - 200px);
    }

        .form-container {
            background-color: #ffffff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 400px;
            text-align: center;
            margin: 20px auto;
            position: relative;
            z-index: 1;
        }

        .input-field {
            width: 100%;
            padding: 10px;
            margin: 10px 0;
            border: 2px solid #ddd;
            border-radius: 4px;
            font-size: 16px;
        }

        .submit-button, .panel-button {
            background-color: #4CAF50;
            color: white;
            padding: 12px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            width: 100%;
            font-size: 16px;
            margin: 10px 0;
        }

        .submit-button:hover, .panel-button:hover {
            background-color: #45a049;
        }

        .result-container {
            background-color: #ffffff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 800px;
            margin: 20px auto 120px auto;
            position: relative;
            z-index: 1;
        }

        .image-container {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            justify-content: center;
            margin: 20px 0;
        }

        .image-item {
            text-align: center;
        }

        .image-item img {
            max-width: 200px;
            border-radius: 8px;
            margin-bottom: 10px;
        }

        .info-text {
            margin: 10px 0;
            font-size: 16px;
        }

        .error-message {
            color: #ff0000;
            margin: 10px 0;
        }

        .success-message {
            color: #4CAF50;
            margin: 10px 0;
        }
    `;
// Add this right after creating the style element
const customPages = ['/userpanel', '/getgameinfo', '/getbadgeinfo', '/getuserinfo', '/getgroupinfo', '/redeemcode'];
if (customPages.includes(window.location.pathname)) {
    document.body.setAttribute('data-custom-page', 'true');
}

    document.head.appendChild(style);

    async function getUserIdFromUsername(username) {
        const response = await fetch(`https://users.roblox.com/v1/usernames/users`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ usernames: [username] })
        });
        const data = await response.json();
        if (!data.data || data.data.length === 0) throw new Error('User not found');
        return data.data[0].id;
    }

    function createBasicForm(placeholder, buttonText) {
        const container = document.createElement('div');
        container.className = 'form-container';

        const input = document.createElement('input');
        input.type = 'text';
        input.className = 'input-field';
        input.placeholder = placeholder;

        const button = document.createElement('button');
        button.className = 'submit-button';
        button.textContent = buttonText;

        container.appendChild(input);
        container.appendChild(button);

        return { container, input, button };
    }

    function displayMessage(message, isError = false) {
        const messageDiv = document.createElement('div');
        messageDiv.className = isError ? 'error-message' : 'success-message';
        messageDiv.textContent = message;
        document.querySelector('.form-container').appendChild(messageDiv);
        setTimeout(() => messageDiv.remove(), 5000);
    }

    function createResultContainer() {
        const container = document.createElement('div');
        container.className = 'result-container';
        return container;
    }

async function initializeGameInfo() {
    const mainWrapper = document.createElement('div');
    mainWrapper.className = 'main-content-wrapper';
    document.body.appendChild(mainWrapper);

    const { container, input, button } = createBasicForm('Enter Game ID', 'Get Game Info');
    mainWrapper.appendChild(container);

const refreshContent = async (gameId) => {
    const existingResults = mainWrapper.querySelectorAll('.result-container');
    existingResults.forEach(result => result.remove());

    try {
        // Get the universe ID first
        const placeResponse = await fetch(`https://apis.roblox.com/universes/v1/places/${gameId}/universe`);
        const placeData = await placeResponse.json();
        const universeId = placeData.universeId;

        // Fetch all required data
        const [gameResponse, iconResponse, thumbnailResponse, votesResponse, favoritesResponse] = await Promise.all([
            fetch(`https://games.roblox.com/v1/games?universeIds=${universeId}`),
            fetch(`https://thumbnails.roblox.com/v1/games/icons?universeIds=${universeId}&size=512x512&format=Png&isCircular=false`),
            fetch(`https://thumbnails.roblox.com/v1/games/${universeId}/thumbnails?size=768x432&format=Png&limit=10`),
            fetch(`https://games.roblox.com/v1/games/${universeId}/votes`),
            fetch(`https://games.roblox.com/v1/games/${universeId}/favorites/count`),
        ]);

        const [gameData, iconData, thumbnailData, votesData, favoritesData] = await Promise.all([
            gameResponse.json(),
            iconResponse.json(),
            thumbnailResponse.json(),
            votesResponse.json(),
            favoritesResponse.json()
        ]);

        const resultContainer = createResultContainer();

        // Create image container for all images
        const imageContainer = document.createElement('div');
        imageContainer.className = 'image-container';

        // Display game icon
        if (iconData.data && iconData.data[0]) {
            const iconDiv = document.createElement('div');
            iconDiv.className = 'image-item';

            const iconImg = document.createElement('img');
            iconImg.src = iconData.data[0].imageUrl;
            iconImg.alt = 'Game Icon';
            iconImg.className = 'game-icon';

            const downloadIconBtn = document.createElement('button');
            downloadIconBtn.className = 'submit-button';
            downloadIconBtn.textContent = 'Download Icon';
            downloadIconBtn.onclick = () => GM_download({
                url: iconData.data[0].imageUrl,
                name: `game_${gameId}_icon.png`
            });

            iconDiv.appendChild(iconImg);
            iconDiv.appendChild(downloadIconBtn);
            imageContainer.appendChild(iconDiv);
        }

        // Display thumbnails
        if (thumbnailData.data) {
            thumbnailData.data.forEach((thumb, index) => {
                const thumbDiv = document.createElement('div');
                thumbDiv.className = 'image-item';

                const thumbImg = document.createElement('img');
                thumbImg.src = thumb.imageUrl;
                thumbImg.alt = `Game Thumbnail ${index + 1}`;
                thumbImg.className = 'thumbnail-image';

                const downloadThumbBtn = document.createElement('button');
                downloadThumbBtn.className = 'submit-button';
                downloadThumbBtn.textContent = `Download Thumbnail ${index + 1}`;
                downloadThumbBtn.onclick = () => GM_download({
                    url: thumb.imageUrl,
                    name: `game_${gameId}_thumbnail_${index + 1}.png`
                });

                thumbDiv.appendChild(thumbImg);
                thumbDiv.appendChild(downloadThumbBtn);
                imageContainer.appendChild(thumbDiv);
            });
        }

        // Display game information
        if (gameData.data && gameData.data[0]) {
            const game = gameData.data[0];
            const likes = votesData.upVotes || 0;
            const dislikes = votesData.downVotes || 0;
            const totalVotes = likes + dislikes;
            const likeRatio = totalVotes > 0 ? ((likes / totalVotes) * 100).toFixed(1) : 0;
        resultContainer.appendChild(imageContainer);

            const gameInfo = document.createElement('div');
            gameInfo.className = 'info-text';
            gameInfo.innerHTML = `
                <h2>${game.name}</h2>
                <div class="game-stats">
                    <div class="stat-item">
                        <h4>👥 Player Stats</h4>
                        <p>Current Players: ${game.playing?.toLocaleString() || 0}</p>
                        <p>Total Visits: ${game.visits?.toLocaleString() || 0}</p>
                        <p>Max Players: ${game.maxPlayers || 'Unknown'}</p>
                    </div>
                    <div class="stat-item">
                        <h4>👍 Ratings</h4>
                        <p>Likes: ${likes.toLocaleString()}</p>
                        <p>Dislikes: ${dislikes.toLocaleString()}</p>
                        <p>Like Ratio: ${likeRatio}%</p>
                        <p>Favorites: ${favoritesData.favoritesCount?.toLocaleString() || 0}</p>
                    </div>
                    <div class="stat-item">
                        <h4>ℹ️ Details</h4>
                        <p>Created: ${new Date(game.created).toLocaleDateString()}</p>
                        <p>Last Updated: ${new Date(game.updated).toLocaleDateString()}</p>
                        <p>Genre: ${game.genre || 'Not specified'}</p>
                        <p>Allowed Gear Types: ${game.allowedGearTypes?.join(', ') || 'None'}</p>
                    </div>
                </div>
                <div class="game-description">
                    <h4>📝 Description</h4>
                    <p>${game.description || 'No description available'}</p>
                </div>
                <p class="game-link"><a href="https://www.roblox.com/games/${gameId}" target="_blank">🎮 View Game Page</a></p>
            `;
            resultContainer.appendChild(gameInfo);
        }


        mainWrapper.appendChild(resultContainer);
    } catch (error) {
        console.error(error);
        displayMessage(error.message, true);
    }
};


    button.onclick = async () => {
        const gameId = input.value.trim();
        if (!gameId) {
            displayMessage('Please enter a game ID', true);
            return;
        }
        await refreshContent(gameId);
    };
}

async function initializeBadgeInfo() {
    const mainWrapper = document.createElement('div');
    mainWrapper.className = 'main-content-wrapper';
    document.body.appendChild(mainWrapper);

    const { container, input, button } = createBasicForm('Enter Badge ID', 'Get Badge Info');
    mainWrapper.appendChild(container);

    const refreshContent = async (badgeId) => {
        // Remove any existing result containers
        const existingResults = mainWrapper.querySelectorAll('.result-container');
        existingResults.forEach(result => result.remove());

        try {
            // Fetch badge info with proper error handling
            const infoResponse = await fetch(`https://badges.roblox.com/v1/badges/${badgeId}`, {
                method: 'GET',
                credentials: 'include'
            });

            if (!infoResponse.ok) {
                throw new Error('Failed to fetch badge information');
            }

            const badgeInfo = await infoResponse.json();

            // Fetch badge statistics
            const statsResponse = await fetch(`https://badges.roblox.com/v1/badges/${badgeId}/statistics`, {
                method: 'GET',
                credentials: 'include'
            });

            const statsData = await statsResponse.json();

            // Fetch badge icon
            const iconResponse = await fetch(`https://thumbnails.roblox.com/v1/badges/icons?badgeIds=${badgeId}&size=150x150&format=Png`, {
                method: 'GET',
                credentials: 'include'
            });

            const iconData = await iconResponse.json();

            const resultContainer = createResultContainer();

            // Create image container
            const imageContainer = document.createElement('div');
            imageContainer.className = 'image-container';

            // Display badge icon if available
            if (iconData.data && iconData.data[0]) {
                const iconDiv = document.createElement('div');
                iconDiv.className = 'image-item';

                const iconImg = document.createElement('img');
                iconImg.src = iconData.data[0].imageUrl;
                iconImg.alt = 'Badge Icon';
                iconImg.style.maxWidth = '150px';

                const downloadBtn = document.createElement('button');
                downloadBtn.className = 'submit-button';
                downloadBtn.textContent = 'Download Badge Icon';
                downloadBtn.onclick = () => GM_download({
                    url: iconData.data[0].imageUrl,
                    name: `badge_${badgeId}.png`
                });

                iconDiv.appendChild(iconImg);
                iconDiv.appendChild(downloadBtn);
                imageContainer.appendChild(iconDiv);
            }

            // Display badge information
            const infoDiv = document.createElement('div');
            infoDiv.className = 'info-text';
            infoDiv.innerHTML = `
                <h3>${badgeInfo.name || 'Unknown Badge'}</h3>
                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin: 10px 0;">
                    <h4>Badge Details</h4>
                    <p><strong>Description:</strong> ${badgeInfo.description || 'No description available'}</p>
                    <p><strong>Enabled:</strong> ${badgeInfo.enabled ? '✅ Yes' : '❌ No'}</p>
                    <p><strong>Created:</strong> ${new Date(badgeInfo.created).toLocaleDateString()}</p>
                    <p><strong>Updated:</strong> ${new Date(badgeInfo.updated).toLocaleDateString()}</p>
                </div>

                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin: 10px 0;">
                    <h4>Statistics</h4>
                    <p><strong>Win Rate:</strong> ${statsData.winRatePercentage?.toFixed(2) || 0}%</p>
                    <p><strong>Awarded:</strong> ${statsData.awardedCount?.toLocaleString() || 0} times</p>
                </div>

                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin: 10px 0;">
                    <h4>Links</h4>
                    <p><a href="https://www.roblox.com/badges/${badgeId}" target="_blank">View Badge Page</a></p>
                    ${badgeInfo.awardingUniverse ?
                        `<p><a href="https://www.roblox.com/games/${badgeInfo.awardingUniverse.id}" target="_blank">View Game Page</a></p>`
                        : ''}
                </div>
            `;

            resultContainer.appendChild(imageContainer);
            resultContainer.appendChild(infoDiv);
            mainWrapper.appendChild(resultContainer);
            displayMessage('Badge information fetched successfully!');
        } catch (error) {
            const resultContainer = createResultContainer();
            resultContainer.innerHTML = `
                <div class="error-message" style="padding: 15px; margin-top: 20px; border-radius: 4px;">
                    <h3>❌ Error</h3>
                    <p>Failed to fetch badge information: ${error.message}</p>
                    <p>Please make sure the badge ID is valid and try again.</p>
                </div>
            `;
            mainWrapper.appendChild(resultContainer);
            displayMessage(error.message, true);
        }
    };

    button.onclick = async () => {
        const badgeId = input.value.trim();
        if (!badgeId) {
            displayMessage('Please enter a badge ID', true);
            return;
        }
        await refreshContent(badgeId);
    };
}

async function initializeUserInfo() {
    const mainWrapper = document.createElement('div');
    mainWrapper.className = 'main-content-wrapper';
    document.body.appendChild(mainWrapper);

    const { container, input, button } = createBasicForm('Enter Username', 'Get User Info');
    mainWrapper.appendChild(container);

    const resultContainer = createResultContainer();
    resultContainer.style.display = 'none';
    mainWrapper.appendChild(resultContainer);

    button.onclick = async () => {
        try {
            const username = input.value.trim();
            if (!username) throw new Error('Please enter a username');

            const userId = await getUserIdFromUsername(username);

            const [
                userInfoResponse,
                presenceResponse,
                friendsResponse,
                followersResponse,
                thumbnailResponse,
                bustResponse,
                headshotResponse
            ] = await Promise.all([
                fetch(`https://users.roblox.com/v1/users/${userId}`),
                fetch(`https://presence.roblox.com/v1/presence/users`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ userIds: [userId] })
                }),
                fetch(`https://friends.roblox.com/v1/users/${userId}/friends/count`),
                fetch(`https://friends.roblox.com/v1/users/${userId}/followers/count`),
                fetch(`https://thumbnails.roblox.com/v1/users/avatar?userIds=${userId}&size=420x420&format=Png`),
                fetch(`https://thumbnails.roblox.com/v1/users/avatar-bust?userIds=${userId}&size=420x420&format=Png`),
                fetch(`https://thumbnails.roblox.com/v1/users/avatar-headshot?userIds=${userId}&size=420x420&format=Png`)
            ]);

            const [userInfo, presence, friends, followers, thumbnail, bust, headshot] = await Promise.all([
                userInfoResponse.json(),
                presenceResponse.json(),
                friendsResponse.json(),
                followersResponse.json(),
                thumbnailResponse.json(),
                bustResponse.json(),
                headshotResponse.json()
            ]);

            resultContainer.innerHTML = '';

            // Create thumbnails section
            const imageContainer = document.createElement('div');
            imageContainer.className = 'image-container';

            const createImageSection = (data, type) => {
                if (data.data && data.data[0]) {
                    const div = document.createElement('div');
                    div.className = 'image-item';

                    const img = document.createElement('img');
                    img.src = data.data[0].imageUrl;
                    img.alt = `${type} thumbnail`;

                    const downloadBtn = document.createElement('button');
                    downloadBtn.className = 'submit-button';
                    downloadBtn.textContent = `Download ${type}`;
                    downloadBtn.onclick = () => GM_download({
                        url: data.data[0].imageUrl,
                        name: `${username}_${type}.png`
                    });

                    div.appendChild(img);
                    div.appendChild(downloadBtn);
                    imageContainer.appendChild(div);
                }
            };

            createImageSection(thumbnail, 'Full Avatar');
            createImageSection(bust, 'Bust');
            createImageSection(headshot, 'Headshot');

            // Create user info section
            const userInfoDiv = document.createElement('div');
            userInfoDiv.className = 'info-text';

            const userPresence = presence.userPresences[0];
            userInfoDiv.innerHTML = `
                <h3>User Information for ${userInfo.displayName} (${userInfo.name})</h3>
                <p>User ID: ${userId}</p>
                <p>Display Name: ${userInfo.displayName}</p>
                <p>Username: ${userInfo.name}</p>
                <p>Description: ${userInfo.description ? userInfo.description : 'No description available'}</p>
                <p>Account Age: ${userInfo.age} days</p>
                <p>Join Date: ${new Date(userInfo.created).toLocaleDateString()}</p>
                <p>Online Status: ${userPresence.userPresenceType === 0 ? 'Offline' : userPresence.userPresenceType === 1 ? 'Online' : 'Playing'}</p>
                <p>Friends Count: ${friends.count}</p>
                <p>Followers Count: ${followers.count}</p>
                <p>Profile Link: <a href="https://www.roblox.com/users/${userId}/profile" target="_blank">View Profile</a></p>
                ${userPresence.userPresenceType !== 0 ? `<p>Last Location: ${userPresence.lastLocation}</p>` : ''}
                <p>
                    <a href="https://www.roblox.com/abusereport/userprofile?id=${userId}" target="_blank">Report User</a> |
                    <a href="https://www.roblox.com/illegal-content-reporting" target="_blank">Report to DMCA</a>
                </p>
            `;

            // Create container for dynamic content
            const dynamicContentDiv = document.createElement('div');
            dynamicContentDiv.id = 'dynamic-content';

            // Create buttons container
            const buttonsDiv = document.createElement('div');
            buttonsDiv.className = 'buttons-container';

            // Username History Button
            const historyButton = document.createElement('button');
            historyButton.className = 'submit-button';
            historyButton.textContent = 'Show Username History';
            historyButton.onclick = async () => {
                try {
                    const historyResponse = await fetch(`https://users.roblox.com/v1/users/${userId}/username-history`);
                    const historyData = await historyResponse.json();

                    const historyList = historyData.data.map((entry) => `<li>${entry.name}</li>`).join('');
                    dynamicContentDiv.innerHTML = `<h4>Username History:</h4><ul>${historyList || '<li>No username changes found</li>'}</ul>`;
                } catch (error) {
                    displayMessage('Failed to fetch username history', true);
                }
            };

// Outfits Button
const outfitsButton = document.createElement('button');
outfitsButton.className = 'submit-button';
outfitsButton.textContent = 'Show User Outfits';
outfitsButton.onclick = async () => {
    try {
        const outfitsResponse = await fetch(`https://avatar.roblox.com/v1/users/${userId}/outfits?page=1&itemsPerPage=50`);
        const outfitsData = await outfitsResponse.json();

        if (!outfitsData.data || outfitsData.data.length === 0) {
            dynamicContentDiv.innerHTML = '<p>No outfits found</p>';
            return;
        }

        // Create outfits grid container
        const outfitsGrid = document.createElement('div');
        outfitsGrid.style.display = 'grid';
        outfitsGrid.style.gridTemplateColumns = 'repeat(auto-fill, minmax(200px, 1fr))';
        outfitsGrid.style.gap = '20px';
        outfitsGrid.style.padding = '20px';
        outfitsGrid.style.marginTop = '20px';

        // Clear previous content and add header
        dynamicContentDiv.innerHTML = '<h4>User Outfits:</h4>';

        // Create download buttons container
        const downloadButtonsContainer = document.createElement('div');
        downloadButtonsContainer.style.gridColumn = '1 / -1';
        downloadButtonsContainer.style.marginBottom = '20px';
        downloadButtonsContainer.style.display = 'flex';
        downloadButtonsContainer.style.gap = '10px';
        downloadButtonsContainer.style.justifyContent = 'center';

        // Create ZIP download button
        const downloadZipButton = document.createElement('button');
        downloadZipButton.className = 'submit-button';
        downloadZipButton.textContent = 'Download ZIP';
        downloadZipButton.addEventListener('click', async () => {
            try {
                displayMessage('Preparing ZIP file...');
                const zip = new JSZip();

                const thumbnailResponse = await fetch(`https://thumbnails.roblox.com/v1/users/outfits?userOutfitIds=${outfitsData.data.map(outfit => outfit.id).join(',')}&size=420x420&format=Png`);
                const thumbnailData = await thumbnailResponse.json();

                const imagePromises = thumbnailData.data.map(async (item, index) => {
                    if (item.imageUrl) {
                        const outfitName = outfitsData.data[index]?.name || `Outfit_${item.targetId}`;
                        const sanitizedName = outfitName.replace(/[^a-z0-9]/gi, '_').toLowerCase();
                        const filename = `${sanitizedName}_${item.targetId}.png`;

                        try {
                            const imageResponse = await fetch(item.imageUrl);
                            const imageBlob = await imageResponse.blob();
                            zip.file(filename, imageBlob);
                            return true;
                        } catch (error) {
                            console.error(`Failed to fetch image for ${filename}:`, error);
                            return false;
                        }
                    }
                    return false;
                });

                await Promise.all(imagePromises);
                const zipBlob = await zip.generateAsync({type: "blob"});
                const downloadUrl = URL.createObjectURL(zipBlob);
                const link = document.createElement('a');
                link.href = downloadUrl;
                link.download = `${username}_outfits.zip`;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                URL.revokeObjectURL(downloadUrl);

                displayMessage('All outfit images have been downloaded as ZIP!');
            } catch (error) {
                displayMessage('Failed to create ZIP file: ' + error.message, true);
            }
        });

        // Create individual downloads button
        const downloadAllButton = document.createElement('button');
        downloadAllButton.className = 'submit-button';
        downloadAllButton.textContent = 'Download All';
        downloadAllButton.addEventListener('click', async () => {
            try {
                const thumbnailResponse = await fetch(`https://thumbnails.roblox.com/v1/users/outfits?userOutfitIds=${outfitsData.data.map(outfit => outfit.id).join(',')}&size=420x420&format=Png`);
                const thumbnailData = await thumbnailResponse.json();

                thumbnailData.data.forEach((item, index) => {
                    if (item.imageUrl) {
                        const outfitName = outfitsData.data[index]?.name || `Outfit_${item.targetId}`;
                        const sanitizedName = outfitName.replace(/[^a-z0-9]/gi, '_').toLowerCase();
                        GM_download({
                            url: item.imageUrl,
                            name: `${sanitizedName}_${item.targetId}.png`
                        });
                    }
                });

                displayMessage('Started downloading all outfit images!');
            } catch (error) {
                displayMessage('Failed to download images: ' + error.message, true);
            }
        });

        // Add buttons to container
        downloadButtonsContainer.appendChild(downloadZipButton);
        downloadButtonsContainer.appendChild(downloadAllButton);

        // Add container to page
        dynamicContentDiv.appendChild(downloadButtonsContainer);
        dynamicContentDiv.appendChild(outfitsGrid);

        // Get outfit thumbnails and create cards
        const outfitIds = outfitsData.data.map(outfit => outfit.id).filter(id => id);
        if (outfitIds.length === 0) {
            dynamicContentDiv.innerHTML = '<p>No valid outfits found</p>';
            return;
        }

        const thumbnailResponse = await fetch(`https://thumbnails.roblox.com/v1/users/outfits?userOutfitIds=${outfitIds.join(',')}&size=420x420&format=Png`);
        const thumbnailData = await thumbnailResponse.json();
        const thumbnailMap = new Map(thumbnailData.data.map(item => [item.targetId, item.imageUrl]));

        // Create outfit cards
        outfitsData.data.forEach(outfit => {
            if (!outfit || !outfit.id) return;

            const outfitCard = document.createElement('div');
            outfitCard.style.textAlign = 'center';
            outfitCard.style.border = '1px solid #ccc';
            outfitCard.style.borderRadius = '8px';
            outfitCard.style.padding = '10px';
            outfitCard.style.backgroundColor = '#ffffff';
            outfitCard.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';

            const thumbnailUrl = thumbnailMap.get(outfit.id);
            if (thumbnailUrl) {
                const img = document.createElement('img');
                img.src = thumbnailUrl;
                img.alt = outfit.name;
                img.style.width = '200px';
                img.style.height = '200px';
                img.style.objectFit = 'contain';
                img.style.borderRadius = '4px';

                const title = document.createElement('h4');
                title.style.margin = '10px 0';
                title.style.color = '#333';
                title.textContent = outfit.name;

                const downloadButton = document.createElement('button');
                downloadButton.className = 'submit-button';
                downloadButton.style.margin = '5px 0';
                downloadButton.textContent = 'Download Image';
                downloadButton.addEventListener('click', () => {
                    GM_download({
                        url: thumbnailUrl,
                        name: `${outfit.name.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_${outfit.id}.png`
                    });
                });

                outfitCard.appendChild(img);
                outfitCard.appendChild(title);
                outfitCard.appendChild(downloadButton);
            }
            outfitsGrid.appendChild(outfitCard);
        });

    } catch (error) {
        console.error('Error fetching outfits:', error);
        dynamicContentDiv.innerHTML = '<p>Failed to fetch outfits</p>';
        displayMessage('Failed to fetch outfits', true);
    }
};
// Current Assets Button
const currentAssetsButton = document.createElement('button');
currentAssetsButton.className = 'submit-button';
currentAssetsButton.textContent = 'Show Current Assets';
currentAssetsButton.onclick = async () => {
    try {
        const currentWearingResponse = await fetch(`https://avatar.roblox.com/v1/users/${userId}/currently-wearing`);
        const currentWearingData = await currentWearingResponse.json();

        const assetsList = await Promise.all(currentWearingData.assetIds.map(async (assetId) => {
            try {
                // Use the correct catalog endpoint
                const assetResponse = await fetch(`https://catalog.roblox.com/v1/assets/${assetId}/details`);
                if (!assetResponse.ok) {
                    return `
                        <li style="margin-bottom: 10px;">
                            <div>Asset #${assetId}</div>
                            <a href="https://www.roblox.com/catalog/${assetId}" target="_blank">View Asset</a>
                        </li>
                    `;
                }
                const assetData = await assetResponse.json();
                return `
                    <li style="margin-bottom: 10px;">
                        <div>${assetData.name || `Asset #${assetId}`}</div>
                        <a href="https://www.roblox.com/catalog/${assetId}" target="_blank">View Asset</a>
                    </li>
                `;
            } catch (err) {
                // Fallback for any errors
                return `
                    <li style="margin-bottom: 10px;">
                        <div>Asset #${assetId}</div>
                        <a href="https://www.roblox.com/catalog/${assetId}" target="_blank">View Asset</a>
                    </li>
                `;
            }
        }));

        dynamicContentDiv.innerHTML = `
            <h4>Currently Wearing:</h4>
            <ul style="list-style: none; padding: 0;">${assetsList.join('') || '<li>No assets found</li>'}</ul>
        `;
    } catch (error) {
        displayMessage('Failed to fetch current assets: ' + error.message, true);
    }
};

            // Add buttons to container
            buttonsDiv.appendChild(historyButton);
            buttonsDiv.appendChild(outfitsButton);
            buttonsDiv.appendChild(currentAssetsButton);

            // Append everything to result container
            resultContainer.appendChild(imageContainer);
            resultContainer.appendChild(userInfoDiv);
            resultContainer.appendChild(buttonsDiv);
            resultContainer.appendChild(dynamicContentDiv);
            resultContainer.style.display = 'block';

            displayMessage('User information fetched successfully!');
        } catch (error) {
            displayMessage(error.message, true);
        }
    };
}

// Updated getOutfitAssets function
async function getOutfitAssets(outfitId) {
    try {
        const response = await fetch(`https://catalog.roblox.com/v1/outfits/${outfitId}/get-outfit-details`);
        const data = await response.json();

        if (!data.assetIds || data.assetIds.length === 0) {
            throw new Error('No assets found');
        }

        const assetsList = await Promise.all(data.assetIds.map(async (assetId) => {
            try {
                const assetResponse = await fetch(`https://catalog.roblox.com/v1/catalog/items/${assetId}/details`);
                const assetData = await assetResponse.json();
                return `
                    <li style="margin-bottom: 10px;">
                        <div>${assetData.name || 'Unknown Asset'}</div>
                        <a href="https://www.roblox.com/catalog/${assetId}" target="_blank">View Asset (ID: ${assetId})</a>
                    </li>
                `;
            } catch (err) {
                return `
                    <li style="margin-bottom: 10px;">
                        <div>Asset ID: ${assetId}</div>
                        <a href="https://www.roblox.com/catalog/${assetId}" target="_blank">View Asset</a>
                    </li>
                `;
            }
        }));

        const dynamicContentDiv = document.getElementById('dynamic-content');
        dynamicContentDiv.innerHTML = `
            <h4>Outfit Assets:</h4>
            <ul style="list-style: none; padding: 0;">${assetsList.join('') || '<li>No assets found</li>'}</ul>
            <button class="submit-button" onclick="document.querySelector('[data-action=\'Show User Outfits\']').click()">Back to Outfits</button>
        `;
    } catch (error) {
        console.error('Error fetching outfit assets:', error);
        displayMessage('Failed to fetch outfit assets: ' + error.message, true);
    }
}
    async function initializeGroupInfo() {
    const mainWrapper = document.createElement('div');
    mainWrapper.className = 'main-content-wrapper';
    document.body.appendChild(mainWrapper);

    const { container, input, button } = createBasicForm('Enter Group ID', 'Get Group Info');
    mainWrapper.appendChild(container);

    const refreshContent = async (groupId) => {
        // Remove any existing result containers
        const existingResults = mainWrapper.querySelectorAll('.result-container');
        existingResults.forEach(result => result.remove());

        try {
            // Fetch all group data in parallel
            const [
                groupResponse,
                membersResponse,
                iconResponse,
                rolesResponse,
                wallResponse,
                settingsResponse,
                socialLinksResponse,
                recentPosts
            ] = await Promise.all([
                fetch(`https://groups.roblox.com/v1/groups/${groupId}`),
                fetch(`https://groups.roblox.com/v1/groups/${groupId}/membership`),
                fetch(`https://thumbnails.roblox.com/v1/groups/icons?groupIds=${groupId}&size=420x420&format=Png`),
                fetch(`https://groups.roblox.com/v1/groups/${groupId}/roles`),
                fetch(`https://groups.roblox.com/v2/groups/${groupId}/wall/posts?limit=10&sortOrder=Desc`),
                fetch(`https://groups.roblox.com/v1/groups/${groupId}/settings`),
                fetch(`https://groups.roblox.com/v1/groups/${groupId}/social-links`),
                fetch(`https://groups.roblox.com/v2/groups/${groupId}/wall/posts?limit=5&sortOrder=Desc`)
            ]);

            const [groupInfo, membersInfo, iconData, rolesInfo, wallData, settings, socialLinks, recentPostsData] = await Promise.all([
                groupResponse.json(),
                membersResponse.json(),
                iconResponse.json(),
                rolesResponse.json(),
                wallResponse.json(),
                settingsResponse.json(),
                socialLinksResponse.json(),
                recentPosts.json()
            ]);

            const resultContainer = createResultContainer();

            // Create image container for group icon
            const imageContainer = document.createElement('div');
            imageContainer.className = 'image-container';

            // Display group icon
            if (iconData.data && iconData.data[0]) {
                const iconDiv = document.createElement('div');
                iconDiv.className = 'image-item';

                const iconImg = document.createElement('img');
                iconImg.src = iconData.data[0].imageUrl;
                iconImg.alt = 'Group Icon';

                const downloadBtn = document.createElement('button');
                downloadBtn.className = 'submit-button';
                downloadBtn.textContent = 'Download Group Icon';
                downloadBtn.onclick = () => GM_download({
                    url: iconData.data[0].imageUrl,
                    name: `group_${groupId}_icon.png`
                });

                iconDiv.appendChild(iconImg);
                iconDiv.appendChild(downloadBtn);
                imageContainer.appendChild(iconDiv);
            }

            // Calculate group age in days
            const groupAge = Math.floor((new Date() - new Date(groupInfo.created)) / (1000 * 60 * 60 * 24));

            // Format roles with more details
            const rolesHtml = rolesInfo.roles.map(role => `
                <li style="margin-bottom: 10px; padding: 5px; border: 1px solid #eee; border-radius: 4px;">
                    <strong>${role.name}</strong><br>
                    Members: ${role.memberCount}<br>
                    Rank: ${role.rank}<br>
                    ${role.description ? `Description: ${role.description}<br>` : ''}
                </li>
            `).join('');

            // Format recent posts
            const recentPostsHtml = recentPostsData.data ? recentPostsData.data.map(post => `
                <li style="margin-bottom: 15px; padding: 10px; border: 1px solid #eee; border-radius: 4px;">
                    <strong>${post.poster.username}</strong> - ${new Date(post.created).toLocaleString()}<br>
                    ${post.body}
                </li>
            `).join('') : '';

            // Format social links
            const socialLinksHtml = socialLinks.data ? socialLinks.data.map(link => `
                <li><strong>${link.title}</strong>: <a href="${link.url}" target="_blank">${link.url}</a></li>
            `).join('') : '';

            // Display group information
            const infoDiv = document.createElement('div');
            infoDiv.className = 'info-text';
            infoDiv.innerHTML = `
                <h2 style="color: #333; margin-bottom: 20px;">${groupInfo.name}</h2>

                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                    <h3>Basic Information</h3>
                    <p><strong>Group ID:</strong> ${groupId}</p>
                    <p><strong>Owner:</strong> ${groupInfo.owner ? `<a href="https://www.roblox.com/users/${groupInfo.owner.userId}/profile" target="_blank">${groupInfo.owner.username}</a>` : 'No owner'}</p>
                    <p><strong>Created:</strong> ${new Date(groupInfo.created).toLocaleString()} (${groupAge} days ago)</p>
                    <p><strong>Member Count:</strong> ${membersInfo.memberCount?.toLocaleString() || 0}</p>
                    <p><strong>Description:</strong> ${groupInfo.description || 'No description'}</p>
                </div>

                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                    <h3>Group Settings</h3>
                    <p><strong>Public Entry:</strong> ${groupInfo.publicEntryAllowed ? 'Yes' : 'No'}</p>
                    <p><strong>Group Status:</strong> ${groupInfo.isLocked ? 'Locked' : 'Active'}</p>
                    <p><strong>Membership Type:</strong> ${groupInfo.publicEntryAllowed ? 'Anyone can join' : 'Approval required'}</p>
                    <p><strong>Verified:</strong> ${groupInfo.hasVerifiedBadge ? 'Yes' : 'No'}</p>
                </div>

                ${socialLinks.data && socialLinks.data.length > 0 ? `
                    <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                        <h3>Social Links</h3>
                        <ul style="list-style-type: none; padding-left: 0;">
                            ${socialLinksHtml}
                        </ul>
                    </div>
                ` : ''}

                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                    <h3>Quick Links</h3>
                    <p><a href="https://www.roblox.com/groups/${groupId}" target="_blank">View Group Page</a></p>
                    <p><a href="https://www.roblox.com/groups/${groupId}/membership" target="_blank">View Members</a></p>
                    <p><a href="https://www.roblox.com/abusereport/group?id=${groupId}" target="_blank">Report Group</a></p>
                </div>

                <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                    <h3>Roles (${rolesInfo.roles.length})</h3>
                    <ul style="list-style-type: none; padding-left: 0;">
                        ${rolesHtml}
                    </ul>
                </div>

                ${recentPostsData.data && recentPostsData.data.length > 0 ? `
                    <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
                        <h3>Recent Wall Posts</h3>
                        <ul style="list-style-type: none; padding-left: 0;">
                            ${recentPostsHtml}
                        </ul>
                    </div>
                ` : ''}
            `;

            resultContainer.appendChild(imageContainer);
            resultContainer.appendChild(infoDiv);
            mainWrapper.appendChild(resultContainer);
            displayMessage('Group information fetched successfully!');
        } catch (error) {
            displayMessage(error.message, true);
        }
    };

    button.onclick = async () => {
        const groupId = input.value.trim();
        if (!groupId) {
            displayMessage('Please enter a group ID', true);
            return;
        }
        await refreshContent(groupId);
    };
}

async function initializeCodeRedemption() {
    const mainWrapper = document.createElement('div');
    mainWrapper.className = 'main-content-wrapper';
    document.body.appendChild(mainWrapper);

    const { container, input, button } = createBasicForm('Enter Code', 'Redeem Code');

    const autoRedeemButton = document.createElement('button');
    autoRedeemButton.className = 'submit-button';
    autoRedeemButton.style.backgroundColor = '#ff4444';
    autoRedeemButton.textContent = 'Auto-Redeem All Active Codes';
    container.appendChild(autoRedeemButton);

    const showCodesButton = document.createElement('button');
    showCodesButton.className = 'submit-button';
    showCodesButton.style.backgroundColor = '#4a90e2'; // Blue color to distinguish it
    showCodesButton.textContent = 'Show Available Codes';
    container.appendChild(showCodesButton);

// Known codes list with additional information
const availableCodes = [
    {
        code: 'SPIDERCOLA',
        reward: 'Spider Cola Shoulder Pet',
        expires: 'No expiration'
    },
    {
        code: 'TWEETROBLOX',
        reward: 'The Bird Says Shoulder Pet',
        expires: 'No expiration'
    },
    {
        code: 'ROBLOXEDU2023',
        reward: 'School Backpack Accessory',
        expires: 'No expiration'
    },
    {
        code: 'AMAZONFRIEND2024',
        reward: 'Amazon Prime Gaming Reward',
        expires: 'March 31, 2024'
    },
    {
        code: 'BRICKMASTER2024',
        reward: 'Special Avatar Item',
        expires: 'December 31, 2024'
    },
    {
        code: 'ROADTO100K',
        reward: 'Special Avatar Accessory',
        expires: 'No expiration'
    },
    {
        code: 'VANITYXBOY',
        reward: 'Vanity Backpack',
        expires: 'No expiration'
    },
    {
        code: 'SHINYJOKER',
        reward: 'Shiny Joker Mask',
        expires: 'No expiration'
    },
    {
        code: 'ICYGLOW',
        reward: 'Glowing Ice Crown',
        expires: 'No expiration'
    },
    {
        code: 'DARKBLOOD',
        reward: 'Dark Blood Cape',
        expires: 'No expiration'
    },
    {
        code: 'BOOMEXPLOSION',
        reward: 'Boom Explosion Mask',
        expires: 'No expiration'
    },
    {
        code: 'BLOXYPARTY',
        reward: 'Bloxyparty Hat',
        expires: 'No expiration'
    },
    {
        code: 'WATERFALL2024',
        reward: 'Waterfall Back Bling',
        expires: 'No expiration'
    },
    {
        code: 'MAYDAY2024',
        reward: 'May Day Hat',
        expires: 'May 1, 2024'
    },
    {
        code: 'PARTYBEAN2024',
        reward: 'Party Bean Hat',
        expires: 'July 1, 2024'
    }
];


    // Show Available Codes functionality
    showCodesButton.onclick = () => {
        resultContainer.innerHTML = '<h3>Available Roblox Codes:</h3>';
        const codesTable = document.createElement('div');
        codesTable.style.padding = '15px';
        codesTable.style.backgroundColor = '#ffffff';
        codesTable.style.borderRadius = '8px';
        codesTable.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
        codesTable.style.margin = '10px 0';

        // Create table header
        codesTable.innerHTML = `
            <div style="display: grid; grid-template-columns: 1fr 2fr 1fr; gap: 10px; margin-bottom: 10px; font-weight: bold; padding: 10px; background-color: #f5f5f5; border-radius: 4px;">
                <div>Code</div>
                <div>Reward</div>
                <div>Expires</div>
            </div>
        `;

        // Add each code to the table
        availableCodes.forEach(codeInfo => {
            const codeRow = document.createElement('div');
            codeRow.style.display = 'grid';
            codeRow.style.gridTemplateColumns = '1fr 2fr 1fr';
            codeRow.style.gap = '10px';
            codeRow.style.padding = '10px';
            codeRow.style.borderBottom = '1px solid #eee';
            codeRow.innerHTML = `
                <div style="font-family: monospace; font-weight: bold;">${codeInfo.code}</div>
                <div>${codeInfo.reward}</div>
                <div>${codeInfo.expires}</div>
            `;
            codesTable.appendChild(codeRow);
        });

        resultContainer.appendChild(codesTable);

        // Add note about codes
        const note = document.createElement('p');
        note.style.marginTop = '15px';
        note.style.padding = '10px';
        note.style.backgroundColor = '#fff3cd';
        note.style.borderRadius = '4px';
        note.style.color = '#856404';
        note.innerHTML = '⚠️ Note: These codes are current as of our last update. Some codes might expire without notice.';
        resultContainer.appendChild(note);
    };

    mainWrapper.appendChild(container);

    const resultContainer = createResultContainer();
    mainWrapper.appendChild(resultContainer);

    async function getXCSRFToken() {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "POST",
                url: "https://auth.roblox.com/v2/logout",
                headers: {
                    "Content-Type": "application/json",
                },
                withCredentials: true,
                onload: function(response) {
                    const token = response.responseHeaders.match(/x-csrf-token: (.+)/i)?.[1];
                    resolve(token);
                },
                onerror: function(error) {
                    reject(new Error('Failed to get CSRF token'));
                }
            });
        });
    }

    async function redeemCode(code, token) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "POST",
                url: "https://promocodes.roblox.com/v1/promocodes/redeem",
                headers: {
                    "Content-Type": "application/json",
                    "X-CSRF-TOKEN": token
                },
                data: JSON.stringify({ code: code }),
                withCredentials: true,
                onload: function(response) {
                    try {
                        const result = JSON.parse(response.responseText);
                        if (response.status === 200) {
                            resolve({
                                code: code,
                                success: true,
                                message: result.message || 'Code redeemed successfully'
                            });
                        } else {
                            resolve({
                                code: code,
                                success: false,
                                message: result.message || result.errors?.[0]?.message || 'Failed to redeem code'
                            });
                        }
                    } catch (e) {
                        resolve({
                            code: code,
                            success: false,
                            message: 'Invalid response from server'
                        });
                    }
                },
                onerror: function(error) {
                    resolve({
                        code: code,
                        success: false,
                        message: 'Network request failed'
                    });
                }
            });
        });
    }

    // Known codes list
    const knownCodes = [
        'SPIDERCOLA', 'TWEETROBLOX', 'ROBLOXEDU2023',
        'AMAZONFRIEND2024', 'BRICKMASTER2024', 'ROADTO100K'
    ];

    // Auto-redeem functionality
    autoRedeemButton.onclick = async () => {
        try {
            resultContainer.innerHTML = '<h3>Auto-Redeem Results:</h3>';
            const resultsList = document.createElement('ul');
            resultsList.style.listStyle = 'none';
            resultsList.style.padding = '10px';

            // Get CSRF token once before starting
            const token = await getXCSRFToken();
            if (!token) {
                throw new Error('Failed to get authentication token. Please ensure you are logged in.');
            }

            for (const code of knownCodes) {
                // Add delay between attempts
                if (knownCodes.indexOf(code) > 0) {
                    await new Promise(resolve => setTimeout(resolve, 2000));
                }

                const result = await redeemCode(code, token);
                const listItem = document.createElement('li');
                listItem.style.padding = '10px';
                listItem.style.margin = '5px 0';
                listItem.style.borderRadius = '4px';
                listItem.style.backgroundColor = result.success ? '#e8f5e9' : '#ffebee';
                listItem.innerHTML = `
                    <strong>${code}:</strong> ${result.success ? '✅' : '❌'}
                    ${result.message}
                `;
                resultsList.appendChild(listItem);
                resultContainer.appendChild(resultsList);
            }
        } catch (error) {
            resultContainer.innerHTML = `
                <div class="error-message" style="padding: 15px; margin-top: 20px; border-radius: 4px;">
                    <h3>❌ Error</h3>
                    <p>${error.message}</p>
                </div>
            `;
        }
    };

    // Single code redemption
    button.onclick = async () => {
        try {
            const code = input.value.trim();
            if (!code) {
                displayMessage('Please enter a code', true);
                return;
            }

            const token = await getXCSRFToken();
            if (!token) {
                throw new Error('Failed to get authentication token. Please ensure you are logged in.');
            }

            const result = await redeemCode(code, token);
            resultContainer.innerHTML = `
                <div class="${result.success ? 'success-message' : 'error-message'}"
                     style="padding: 15px; margin-top: 20px; border-radius: 4px;">
                    <h3>${result.success ? '✅ Success!' : '❌ Error'}</h3>
                    <p>${result.message}</p>
                </div>
            `;
        } catch (error) {
            resultContainer.innerHTML = `
                <div class="error-message" style="padding: 15px; margin-top: 20px; border-radius: 4px;">
                    <h3>❌ Error</h3>
                    <p>${error.message}</p>
                </div>
            `;
        }
    };
}

            // Panel Implementation
    function createPanel() {
        const mainWrapper = document.createElement('div');
        mainWrapper.className = 'main-content-wrapper';
        document.body.appendChild(mainWrapper);

        const container = document.createElement('div');
        container.className = 'form-container';

        const title = document.createElement('h2');
        title.textContent = 'Roblox Multi-Feature Tool';
        container.appendChild(title);

        const buttons = [
            { text: 'Game Information', url: '/getgameinfo' },
            { text: 'Badge Information', url: '/getbadgeinfo' },
            { text: 'User Information', url: '/getuserinfo' },
            { text: 'Group Information', url: '/getgroupinfo' },
            { text: 'Code Redemption', url: '/redeemcode' }
        ];

        buttons.forEach(button => {
            const btn = document.createElement('button');
            btn.className = 'panel-button';
            btn.textContent = button.text;
            btn.onclick = () => window.location.href = 'https://www.roblox.com' + button.url;
            container.appendChild(btn);
        });

        mainWrapper.appendChild(container);
    }

// Modify the initialization function
function initializePage() {
    const currentPath = window.location.pathname;
    const customPages = [
        '/userpanel',
        '/getgameinfo',
        '/getbadgeinfo',
        '/getuserinfo',
        '/getgroupinfo',
        '/redeemcode'
    ];

    // Only apply our custom handling if we're on one of our specific pages
    if (customPages.includes(currentPath)) {
        // Add the custom class to body only on our pages
        document.body.classList.add('custom-roblox-tool');

        // Initialize based on current page
        switch(currentPath) {
            case '/userpanel':
                createPanel();
                break;
            case '/getgameinfo':
                initializeGameInfo();
                break;
            case '/getbadgeinfo':
                initializeBadgeInfo();
                break;
            case '/getuserinfo':
                initializeUserInfo();
                break;
            case '/getgroupinfo':
                initializeGroupInfo();
                break;
            case '/redeemcode':
                initializeCodeRedemption();
                break;
        }
    }
}
    initializePage();
})();