Gamee Score Modifier

提交你想要的 Gamee 分数

目前為 2025-03-02 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Gamee Score Modifier
// @version      1.0
// @description  提交你想要的 Gamee 分数
// @author       People11
// @match        https://prizes.gamee.com/*
// @grant        GM_xmlhttpRequest
// @namespace https://greasyfork.org/users/1143233
// ==/UserScript==

(function() {
    'use strict';

    // ============ 全局变量 ============
    let lastGameplayData = null; // 保存最近一次的游戏数据
    let authToken = null;        // 认证令牌
    let installUuid = null;      // 安装UUID
    let isSubmittingScore = false; // 防止循环请求的标记

    // ============ 工具函数 ============
    // MD5算法实现 - 用于计算checksum
    function md5(string) {
        function RotateLeft(lValue, iShiftBits) {
            return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
        }

        function AddUnsigned(lX, lY) {
            var lX4, lY4, lX8, lY8, lResult;
            lX8 = (lX & 0x80000000);
            lY8 = (lY & 0x80000000);
            lX4 = (lX & 0x40000000);
            lY4 = (lY & 0x40000000);
            lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
            if (lX4 & lY4) {
                return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
            }
            if (lX4 | lY4) {
                if (lResult & 0x40000000) {
                    return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
                } else {
                    return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
                }
            } else {
                return (lResult ^ lX8 ^ lY8);
            }
        }

        function F(x, y, z) {
            return (x & y) | ((~x) & z);
        }

        function G(x, y, z) {
            return (x & z) | (y & (~z));
        }

        function H(x, y, z) {
            return (x ^ y ^ z);
        }

        function I(x, y, z) {
            return (y ^ (x | (~z)));
        }

        function FF(a, b, c, d, x, s, ac) {
            a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
            return AddUnsigned(RotateLeft(a, s), b);
        }

        function GG(a, b, c, d, x, s, ac) {
            a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
            return AddUnsigned(RotateLeft(a, s), b);
        }

        function HH(a, b, c, d, x, s, ac) {
            a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
            return AddUnsigned(RotateLeft(a, s), b);
        }

        function II(a, b, c, d, x, s, ac) {
            a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
            return AddUnsigned(RotateLeft(a, s), b);
        }

        function ConvertToWordArray(string) {
            var lWordCount;
            var lMessageLength = string.length;
            var lNumberOfWords_temp1 = lMessageLength + 8;
            var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
            var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
            var lWordArray = Array(lNumberOfWords - 1);
            var lBytePosition = 0;
            var lByteCount = 0;
            while (lByteCount < lMessageLength) {
                lWordCount = (lByteCount - (lByteCount % 4)) / 4;
                lBytePosition = (lByteCount % 4) * 8;
                lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
                lByteCount++;
            }
            lWordCount = (lByteCount - (lByteCount % 4)) / 4;
            lBytePosition = (lByteCount % 4) * 8;
            lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
            lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
            lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
            return lWordArray;
        }

        function WordToHex(lValue) {
            var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
            for (lCount = 0; lCount <= 3; lCount++) {
                lByte = (lValue >>> (lCount * 8)) & 255;
                WordToHexValue_temp = "0" + lByte.toString(16);
                WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
            }
            return WordToHexValue;
        }

        function Utf8Encode(string) {
            string = string.replace(/\r\n/g, "\n");
            var utftext = "";

            for (var n = 0; n < string.length; n++) {
                var c = string.charCodeAt(n);

                if (c < 128) {
                    utftext += String.fromCharCode(c);
                } else if ((c > 127) && (c < 2048)) {
                    utftext += String.fromCharCode((c >> 6) | 192);
                    utftext += String.fromCharCode((c & 63) | 128);
                } else {
                    utftext += String.fromCharCode((c >> 12) | 224);
                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                    utftext += String.fromCharCode((c & 63) | 128);
                }
            }

            return utftext;
        }

        var x = Array();
        var k, AA, BB, CC, DD, a, b, c, d;
        var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
        var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
        var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
        var S41 = 6, S42 = 10, S43 = 15, S44 = 21;

        string = Utf8Encode(string);

        x = ConvertToWordArray(string);

        a = 0x67452301;
        b = 0xEFCDAB89;
        c = 0x98BADCFE;
        d = 0x10325476;

        for (k = 0; k < x.length; k += 16) {
            AA = a;
            BB = b;
            CC = c;
            DD = d;
            a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
            d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
            c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
            b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
            a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
            d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
            c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
            b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
            a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
            d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
            c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
            b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
            a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
            d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
            c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
            b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
            a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
            d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
            c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
            b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
            a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
            d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
            c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
            b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
            a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
            d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
            c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
            b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
            a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
            d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
            c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
            b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
            a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
            d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
            c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
            b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
            a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
            d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
            c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
            b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
            a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
            d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
            c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
            b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
            a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
            d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
            c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
            b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
            a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
            d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
            c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
            b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
            a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
            d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
            c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
            b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
            a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
            d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
            c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
            b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
            a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
            d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
            c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
            b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
            a = AddUnsigned(a, AA);
            b = AddUnsigned(b, BB);
            c = AddUnsigned(c, CC);
            d = AddUnsigned(d, DD);
        }

        var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);

        return temp.toLowerCase();
    }

    // 计算checksum的函数
    function calculateChecksum(score, playTime, gameUrl, gameStateData, uuid) {
        const saltValue = "crmjbjm3lczhlgnek9uaxz2l9svlfjw14npauhen";
        const checksumString = `${score}:${playTime}:${gameUrl}:${gameStateData || ""}:${uuid}:${saltValue}`;
        console.log("计算checksum的字符串:", checksumString);
        return md5(checksumString);
    }

    // 生成UUID v4
    function generateUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

    // 获取当前时间的ISO字符串
    function getCurrentTimeISO() {
        const now = new Date();
        // 获取年月日
        const year = now.getFullYear();
        const month = String(now.getMonth() + 1).padStart(2, '0');
        const day = String(now.getDate()).padStart(2, '0');
        // 获取时分秒
        const hours = String(now.getHours()).padStart(2, '0');
        const minutes = String(now.getMinutes()).padStart(2, '0');
        const seconds = String(now.getSeconds()).padStart(2, '0');
        // 获取时区
        const tzOffset = now.getTimezoneOffset();
        const tzHours = String(Math.abs(Math.floor(tzOffset / 60))).padStart(2, '0');
        const tzMinutes = String(Math.abs(tzOffset % 60)).padStart(2, '0');
        const tzSign = tzOffset <= 0 ? '+' : '-';
        return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}${tzSign}${tzHours}:${tzMinutes}`;
    }

    // 获取下一个gameplayId
    function getNextGameplayId() {
        // 从localStorage中获取当前最大值
        let currentMax = localStorage.getItem('gameeScoreModifier_maxGameplayId');
        if (!currentMax && lastGameplayData && lastGameplayData.metadata && lastGameplayData.metadata.gameplayId) {
            currentMax = lastGameplayData.metadata.gameplayId;
        }
        // 如果仍然为空,则从555开始
        currentMax = currentMax ? parseInt(currentMax, 10) : 555;
        // 增加并保存新值
        const nextId = currentMax + 1;
        localStorage.setItem('gameeScoreModifier_maxGameplayId', nextId.toString());
        return nextId;
    }

    // 从cookie获取认证信息
    function getCookieValue(cookieName) {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // 检查cookie是否以给定的名称开头
            if (cookie.indexOf(cookieName + '=') === 0) {
                // 返回cookie的值部分
                return cookie.substring(cookieName.length + 1);
            }
        }
        return null;
    }

    // 设置网络捕获和拦截
    function setupNetworkCapture() {
        console.log('设置网络捕获...');

        // 从cookie中获取认证信息
        try {
            // 从cookie中获取认证token
            const authCookie = getCookieValue('authentication');
            if (authCookie) {
                authToken = "Bearer " + authCookie;
                console.log('从cookie找到认证令牌: authentication');
            }

            // 从cookie中获取UUID
            const uuidCookie = getCookieValue('uuid');
            if (uuidCookie) {
                installUuid = uuidCookie;
                console.log('从cookie找到UUID: uuid');
            }
        } catch (e) {
            console.error('从cookie获取认证信息时出错:', e);
        }

        // 拦截XHR请求以捕获游戏数据
        const originalXHROpen = XMLHttpRequest.prototype.open;
        const originalXHRSend = XMLHttpRequest.prototype.send;

        XMLHttpRequest.prototype.open = function(method, url) {
            this._url = url;
            this._method = method;
            return originalXHROpen.apply(this, arguments);
        };

        XMLHttpRequest.prototype.send = function(body) {
            // 避免捕获我们自己的修改请求
            if (this._url && this._url.includes('api.gamee.com') && !isSubmittingScore) {
                // 尝试从请求体中捕获游戏数据
                if (body && typeof body === 'string') {
                    try {
                        const data = JSON.parse(body);
                        if (data.method === 'game.saveWebGameplay' && data.params && data.params.gameplayData) {
                            lastGameplayData = data.params.gameplayData;
                            console.log('捕获到游戏数据:', lastGameplayData);

                            // 更新状态徽章
                            updateStatusBadge();
                        }
                    } catch (e) {
                        console.error('解析请求体失败:', e);
                    }
                }
            }
            return originalXHRSend.apply(this, arguments);
        };

        // 拦截fetch请求以捕获游戏数据
        const originalFetch = window.fetch;
        window.fetch = function(input, init) {
            // 只拦截对Gamee API的请求
            if (input && typeof input === 'string' && input.includes('api.gamee.com') && !isSubmittingScore) {
                // 如果有请求体,尝试捕获游戏数据
                if (init && init.body && typeof init.body === 'string') {
                    try {
                        const data = JSON.parse(init.body);
                        if (data.method === 'game.saveWebGameplay' && data.params && data.params.gameplayData) {
                            lastGameplayData = data.params.gameplayData;
                            console.log('捕获到游戏数据:', lastGameplayData);

                            // 更新状态徽章
                            updateStatusBadge();
                        }
                    } catch (e) {
                        console.error('解析fetch请求体失败:', e);
                    }
                }
            }
            // 对于所有请求,直接传递给原始fetch
            return originalFetch.apply(this, arguments);
        };
    }

    // ============ UI界面 ============
    // 创建状态徽章
    function addStatusBadge() {
        let badge = document.getElementById('gamee-score-modifier-badge');

        // 如果徽章已存在,则移除它
        if (badge) {
            badge.remove();
        }

        // 创建新徽章
        badge = document.createElement('div');
        badge.id = 'gamee-score-modifier-badge';
        badge.style.position = 'fixed';
        badge.style.bottom = '10px';
        badge.style.right = '10px';
        badge.style.backgroundColor = '#f44336';
        badge.style.color = 'white';
        badge.style.padding = '5px 10px';
        badge.style.borderRadius = '5px';
        badge.style.fontSize = '12px';
        badge.style.zIndex = '9999';
        badge.style.cursor = 'pointer';
        badge.textContent = '未捕获游戏数据';
        badge.title = '点击打开分数修改器';

        badge.addEventListener('click', createScoreModifierDialog);

        document.body.appendChild(badge);

        // 更新徽章状态
        updateStatusBadge();
    }

    // 更新状态徽章
    function updateStatusBadge() {
        const badge = document.getElementById('gamee-score-modifier-badge');
        if (badge) {
            if (lastGameplayData) {
                badge.style.backgroundColor = '#4CAF50';
                badge.textContent = `已捕获游戏数据: ${lastGameplayData.gameId} (分数: ${lastGameplayData.score})`;
            } else {
                badge.style.backgroundColor = '#f44336';
                badge.textContent = '未捕获游戏数据';
            }
        }
    }

    // 创建修改分数的弹窗
    function createScoreModifierDialog() {
        if (!lastGameplayData) {
            alert('尚未捕获到游戏数据,请先玩一次游戏并提交分数');
            return;
        }

        // 创建对话框元素
        const dialog = document.createElement('div');
        dialog.style.position = 'fixed';
        dialog.style.top = '50%';
        dialog.style.left = '50%';
        dialog.style.transform = 'translate(-50%, -50%)';
        dialog.style.backgroundColor = 'white';
        dialog.style.padding = '20px';
        dialog.style.borderRadius = '5px';
        dialog.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
        dialog.style.zIndex = '10000';
        dialog.style.width = '500px';
        dialog.style.maxHeight = '80vh';
        dialog.style.overflowY = 'auto';

        // 添加标题
        const title = document.createElement('h2');
        title.textContent = '修改游戏分数';
        title.style.marginTop = '0';
        dialog.appendChild(title);

        // 添加游戏信息
        const gameInfo = document.createElement('div');
        gameInfo.innerHTML = `
            <p><strong>游戏ID:</strong> ${lastGameplayData.gameId}</p>
            <p><strong>游戏URL:</strong> ${lastGameplayData.gameUrl}</p>
            <p><strong>版本号:</strong> ${lastGameplayData.releaseNumber}</p>
            <p><strong>当前分数:</strong> ${lastGameplayData.score}</p>
            <p><strong>当前游戏时长:</strong> ${lastGameplayData.playTime} 秒</p>
        `;
        dialog.appendChild(gameInfo);

        // 添加分数输入
        const scoreLabel = document.createElement('label');
        scoreLabel.textContent = '目标分数:';
        scoreLabel.style.display = 'block';
        scoreLabel.style.marginTop = '15px';
        scoreLabel.style.fontWeight = 'bold';
        dialog.appendChild(scoreLabel);

        const scoreInput = document.createElement('input');
        scoreInput.type = 'number';
        scoreInput.value = lastGameplayData.score;
        scoreInput.style.width = '100%';
        scoreInput.style.padding = '8px';
        scoreInput.style.boxSizing = 'border-box';
        scoreInput.style.marginBottom = '5px';
        dialog.appendChild(scoreInput);

        // 添加自动计算结果显示区域
        const resultInfo = document.createElement('div');
        resultInfo.style.marginTop = '15px';
        resultInfo.style.padding = '10px';
        resultInfo.style.backgroundColor = '#f5f5f5';
        resultInfo.style.borderRadius = '5px';
        resultInfo.style.border = '1px solid #ddd';
        resultInfo.style.display = 'none'; // 初始隐藏
        dialog.appendChild(resultInfo);

        // 添加预览按钮
        const previewButton = document.createElement('button');
        previewButton.textContent = '预览修改结果';
        previewButton.style.display = 'block';
        previewButton.style.marginTop = '15px';
        previewButton.style.padding = '8px 16px';
        previewButton.style.backgroundColor = '#2196F3';
        previewButton.style.color = 'white';
        previewButton.style.border = 'none';
        previewButton.style.borderRadius = '4px';
        previewButton.style.cursor = 'pointer';
        dialog.appendChild(previewButton);

        // 如果有游戏状态数据,显示编辑框
        let gameStateInput = null;
        if (lastGameplayData.gameStateData) {
            const gameStateLabel = document.createElement('label');
            gameStateLabel.textContent = '游戏状态数据(JSON):';
            gameStateLabel.style.display = 'block';
            gameStateLabel.style.marginTop = '15px';
            gameStateLabel.style.fontWeight = 'bold';
            dialog.appendChild(gameStateLabel);

            gameStateInput = document.createElement('textarea');
            try {
                // 尝试格式化JSON以便于编辑
                gameStateInput.value = JSON.stringify(JSON.parse(lastGameplayData.gameStateData), null, 2);
            } catch (e) {
                gameStateInput.value = lastGameplayData.gameStateData;
            }
            gameStateInput.style.width = '100%';
            gameStateInput.style.padding = '5px';
            gameStateInput.style.boxSizing = 'border-box';
            gameStateInput.style.height = '150px';
            gameStateInput.style.fontFamily = 'monospace';
            dialog.appendChild(gameStateInput);
        }

        // 为预览按钮添加功能
        previewButton.addEventListener('click', function() {
            const newScore = parseInt(scoreInput.value, 10);

            if (isNaN(newScore) || newScore <= 0) {
                alert('请输入有效的分数值');
                return;
            }

            // 计算分数倍率
            const scoreMultiplier = newScore / lastGameplayData.score;
            // 按照相同比例调整游戏时长
            const newPlayTime = Math.round(lastGameplayData.playTime * scoreMultiplier);

            // 创建新的UUID用于计算
            const newUuid = generateUUID();

            // 计算新的checksum
            const newChecksum = calculateChecksum(
                newScore,
                newPlayTime,
                lastGameplayData.gameUrl,
                gameStateInput ? gameStateInput.value : lastGameplayData.gameStateData,
                newUuid
            );

            // 显示预览结果
            resultInfo.innerHTML = `
                <h3 style="margin-top: 0; color: #2196F3;">修改预览</h3>
                <p><strong>原始分数:</strong> ${lastGameplayData.score}</p>
                <p><strong>修改后分数:</strong> ${newScore} (${scoreMultiplier.toFixed(2)}倍)</p>
                <p><strong>原始游戏时长:</strong> ${lastGameplayData.playTime} 秒</p>
                <p><strong>修改后游戏时长:</strong> ${newPlayTime} 秒</p>
                <p><strong>UUID:</strong> ${newUuid}</p>
                <p><strong>Checksum:</strong> ${newChecksum}</p>
            `;
            resultInfo.style.display = 'block';
        });

        // 添加确定按钮
        const submitButton = document.createElement('button');
        submitButton.textContent = '提交修改后的分数';
        submitButton.style.display = 'block';
        submitButton.style.marginTop = '20px';
        submitButton.style.padding = '8px 16px';
        submitButton.style.backgroundColor = '#4CAF50';
        submitButton.style.color = 'white';
        submitButton.style.border = 'none';
        submitButton.style.borderRadius = '4px';
        submitButton.style.cursor = 'pointer';
        dialog.appendChild(submitButton);

        // 添加取消按钮
        const cancelButton = document.createElement('button');
        cancelButton.textContent = '取消';
        cancelButton.style.display = 'block';
        cancelButton.style.marginTop = '10px';
        cancelButton.style.padding = '8px 16px';
        cancelButton.style.backgroundColor = '#f44336';
        cancelButton.style.color = 'white';
        cancelButton.style.border = 'none';
        cancelButton.style.borderRadius = '4px';
        cancelButton.style.cursor = 'pointer';
        dialog.appendChild(cancelButton);

        // 创建半透明背景
        const overlay = document.createElement('div');
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0,0,0,0.5)';
        overlay.style.zIndex = '9999';

        // 添加关闭对话框的功能
        cancelButton.addEventListener('click', function() {
            document.body.removeChild(dialog);
            document.body.removeChild(overlay);
        });

        // 添加提交功能
        submitButton.addEventListener('click', function() {
            const newScore = parseInt(scoreInput.value, 10);

            if (isNaN(newScore) || newScore <= 0) {
                alert('请输入有效的分数值');
                return;
            }

            // 计算分数倍率
            const scoreMultiplier = newScore / lastGameplayData.score;
            // 按照相同比例调整游戏时长
            const newPlayTime = Math.round(lastGameplayData.playTime * scoreMultiplier);

            // 创建新的游戏数据对象,避免修改原始对象
            const modifiedGameplayData = {...lastGameplayData};

            // 更新分数和游戏时长
            modifiedGameplayData.score = newScore;
            modifiedGameplayData.playTime = newPlayTime;

            // 如果有游戏状态数据编辑框,更新游戏状态数据
            if (gameStateInput) {
                try {
                    // 验证JSON格式
                    JSON.parse(gameStateInput.value);
                    modifiedGameplayData.gameStateData = gameStateInput.value;
                } catch (e) {
                    alert('游戏状态数据不是有效的JSON格式');
                    return;
                }
            }

            // 发送修改后的分数
            sendModifiedScore(modifiedGameplayData);

            // 关闭对话框
            document.body.removeChild(dialog);
            document.body.removeChild(overlay);
        });

        // 添加到页面
        document.body.appendChild(overlay);
        document.body.appendChild(dialog);
    }

    // ============ 分数修改与提交 ============
    // 发送修改后的分数
    function sendModifiedScore(gameplayData) {
        // 生成新的唯一标识符
        const newUuid = generateUUID();
        const newCreatedTime = getCurrentTimeISO();
        const newGameplayId = getNextGameplayId();

        // 创建新的gameplay数据对象,避免修改原始对象
        const modifiedGameplayData = {...gameplayData};

        // 更新唯一标识
        modifiedGameplayData.uuid = newUuid;
        modifiedGameplayData.createdTime = newCreatedTime;
        if (modifiedGameplayData.metadata) {
            modifiedGameplayData.metadata = {...modifiedGameplayData.metadata};
            modifiedGameplayData.metadata.gameplayId = newGameplayId;
        } else {
            modifiedGameplayData.metadata = { gameplayId: newGameplayId };
        }

        // 重新计算checksum
        modifiedGameplayData.checksum = calculateChecksum(
            modifiedGameplayData.score,
            modifiedGameplayData.playTime,
            modifiedGameplayData.gameUrl,
            modifiedGameplayData.gameStateData,
            newUuid
        );

        console.log('使用新的唯一标识:', {
            uuid: newUuid,
            createdTime: newCreatedTime,
            gameplayId: newGameplayId,
            checksum: modifiedGameplayData.checksum
        });

        // 设置防止循环请求的标记
        isSubmittingScore = true;

        const requestData = {
            jsonrpc: "2.0",
            id: "game.saveWebGameplay",
            method: "game.saveWebGameplay",
            params: {
                gameplayData: modifiedGameplayData
            }
        };

        console.log('发送修改后的游戏数据:', requestData);

        GM_xmlhttpRequest({
            method: "POST",
            url: "https://api.gamee.com/",
            headers: {
                "Content-Type": "text/plain;charset=UTF-8",
                "Authorization": authToken,
                "X-Install-UUID": installUuid,
                "X-Bot-Header": "gamee",
                "Origin": "https://prizes.gamee.com",
                "Referer": "https://prizes.gamee.com/",
                "User-Agent": navigator.userAgent,
                // 添加额外的标记,避免被脚本拦截
                "X-Score-Modifier": "true"
            },
            data: JSON.stringify(requestData),
            onload: function(response) {
                console.log('分数提交响应:', response.responseText);
                try {
                    const result = JSON.parse(response.responseText);
                    if (result.result) {
                        alert('分数修改成功!');
                    } else {
                        alert('分数修改失败:' + JSON.stringify(result.error || '未知错误'));
                    }
                } catch (e) {
                    alert('解析响应失败:' + e.message);
                }
                // 清除标记
                isSubmittingScore = false;
            },
            onerror: function(error) {
                alert('请求出错:' + error.message);
                console.error('请求错误详情:', error);
                // 清除标记
                isSubmittingScore = false;
            }
        });
    }

    // ============ 初始化 ============

    // 页面加载完成后初始化
    function initialize() {
        console.log('Gamee分数修改器初始化中...');
        setupNetworkCapture();
        addStatusBadge();
        console.log('Gamee分数修改器已启动');
    }

    // 检查页面是否已加载
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initialize);
    } else {
        initialize();
    }
})();