MWI角色名片插件

MWI角色名片插件 - 一键生成角色名片

目前為 2025-08-04 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name           MWI角色名片插件
// @name:en        MWI Character Card
// @namespace      http://tampermonkey.net/
// @version        1.3.4
// @license        MIT
// @description    MWI角色名片插件 - 一键生成角色名片
// @description:en MWI Character Business Card Plugin - Generate character business cards with a single click
// @author         Windoge
// @match          https://www.milkywayidle.com/*
// @icon           https://www.milkywayidle.com/favicon.svg
// @run-at         document-idle
// @require        https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
// ==/UserScript==

(function() {
    'use strict';

    // 使用立即执行函数避免全局变量污染
    const MWICharacterCard = (function() {
        const isZHInGameSetting = localStorage.getItem("i18nextLng")?.toLowerCase()?.startsWith("zh"); // 获取游戏内设置语言
        let isZH = isZHInGameSetting; // MWITools 本身显示的语言默认由游戏内设置语言决定
        
        // 检测移动端
        function isMobile() {
            return window.innerWidth <= 768 || /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
        }
        
        // 简化的SVG创建工具
        class CharacterCardSVGTool {
            constructor() {
                this.isLoaded = true; // 简化:直接设为true
                this.spriteSheets = {
                    items: '/static/media/items_sprite.6d12eb9d.svg',
                    skills: '/static/media/skills_sprite.57eb3a30.svg',
                    abilities: '/static/media/abilities_sprite.38932ac3.svg',
                    misc: '/static/media/misc_sprite.6b3198dc.svg'
                };
            }

            async loadSpriteSheets() {
                console.log('SVG sprite系统已初始化');
                console.log('Sprite文件路径:', this.spriteSheets);
                this.isLoaded = true;
                return true;
            }

            // 创建MWI风格的SVG图标 - 直接返回HTML字符串
            createSVGIcon(itemId, options = {}) {
                const { className = 'Icon_icon__2LtL_', title = itemId, type = 'items' } = options;
                const svgHref = `${this.spriteSheets[type]}#${itemId}`;
                
                // 收集调试信息
                if (!state.debugInfo.firstSvgPath) {
                    state.debugInfo.firstSvgPath = svgHref;
                }
                state.debugInfo.iconCount++;
                
                return `<svg role="img" aria-label="${title}" class="${className}" width="100%" height="100%">
                    <use href="${svgHref}"></use>
                </svg>`;
            }

            // 后备图标
            createFallbackIcon(itemId, className, title) {
                const text = itemId.length > 6 ? itemId.substring(0, 6) : itemId;
                return `<div class="${className}" title="${title}" style="
                    width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
                    background: #4a90e2; color: white; font-size: 10px; border-radius: 4px;
                ">${text}</div>`;
            }

            hasIcon() { return this.isLoaded; }
        }

        // 技能选择器相关函数
        function showSkillSelector(skillIndex) {
            // 获取所有可用技能(包括未装备的)
            const allSkills = window.characterCardWebSocketData?.characterAbilities || [];
            const availableSkills = allSkills
                .filter(ability => ability.abilityHrid && ability.abilityHrid.startsWith("/abilities/"))
                .sort((a, b) => (a.slotNumber || 0) - (b.slotNumber || 0));
            
            // 创建技能选择器模态框
            const modal = document.createElement('div');
            modal.className = 'skill-selector-modal';
            modal.innerHTML = `
                <div class="skill-selector-content">
                    <div class="skill-selector-header">
                        <h3>${isZH ? '选择技能' : 'Select Skill'}</h3>
                        <button class="close-skill-selector">&times;</button>
                    </div>
                    <div class="skill-selector-grid">
                        <!-- 空按钮 -->
                        <div class="skill-option empty-skill-option" data-skill-index="${skillIndex}" data-ability-hrid="" data-level="0">
                            <div class="skill-option-icon">
                                <div class="empty-skill-icon">-</div>
                            </div>
                            <div class="skill-option-level">${isZH ? '空' : 'Empty'}</div>
                        </div>
                        ${availableSkills.map(skill => `
                            <div class="skill-option" data-skill-index="${skillIndex}" data-ability-hrid="${skill.abilityHrid}" data-level="${skill.level}">
                                <div class="skill-option-icon">
                                    ${createSvgIcon(skill.abilityHrid, 'abilities')}
                                </div>
                                <div class="skill-option-level">Lv.${skill.level}</div>
                            </div>
                        `).join('')}
                    </div>
                </div>
            `;
            
            // 添加事件监听器
            modal.querySelector('.close-skill-selector').onclick = () => {
                document.body.removeChild(modal);
            };
            modal.onclick = (e) => {
                if (e.target === modal) {
                    document.body.removeChild(modal);
                }
            };
            
            // 添加技能选项点击事件监听器
            const skillOptions = modal.querySelectorAll('.skill-option');
            skillOptions.forEach(option => {
                option.addEventListener('click', function() {
                    const skillIndex = parseInt(this.getAttribute('data-skill-index'));
                    const abilityHrid = this.getAttribute('data-ability-hrid');
                    const level = parseInt(this.getAttribute('data-level'));
                    selectSkill(skillIndex, abilityHrid, level);
                });
            });
            
            document.body.appendChild(modal);
        }
        
        function selectSkill(skillIndex, abilityHrid, level) {
            // 更新用户选择的技能
            if (abilityHrid === "") {
                // 选择"空"选项,删除该位置的技能
                delete state.customSkills.selectedSkills[skillIndex];
            } else {
                // 选择具体技能
                state.customSkills.selectedSkills[skillIndex] = {
                    abilityHrid: abilityHrid,
                    level: level,
                    slotNumber: skillIndex + 1
                };
            }
            
                            // 重新生成技能面板
                const characterCard = document.querySelector('#character-card');
                if (characterCard) {
                    const skillPanel = characterCard.querySelector('.skill-panel');
                    if (skillPanel) {
                        // 重新生成技能面板内容
                        const characterData = {
                            abilities: window.characterCardWebSocketData?.characterAbilities || [],
                            characterSkills: window.characterCardWebSocketData?.characterSkills || []
                        };
                        const newSkillPanel = generateSkillPanel(characterData, true);
                        skillPanel.innerHTML = newSkillPanel.replace(/<div class="skill-panel">([\s\S]*?)<\/div>$/, '$1');
                        
                        // 重新添加事件监听器
                        const skillSlots = skillPanel.querySelectorAll('.skill-slot, .empty-skill-slot');
                        skillSlots.forEach(slot => {
                            slot.addEventListener('click', function() {
                                const skillIndex = parseInt(this.getAttribute('data-skill-index'));
                                showSkillSelector(skillIndex);
                            });
                        });
                    }
                }
            
            // 关闭技能选择器
            const modal = document.querySelector('.skill-selector-modal');
            if (modal) {
                document.body.removeChild(modal);
            }
        }
        
        // 全局版本号
        const VERSION = '1.3.2';
        
        // 使用闭包管理状态,避免全局变量
        const state = {
            svgTool: new CharacterCardSVGTool(),
            debugInfo: {
                firstSvgPath: null,
                iconCount: 0
            },
            observer: null,
            timer: null,
            isInitialized: false,
            // 用户自定义技能展示状态
            customSkills: {
                selectedSkills: [], // 用户选择的技能列表
                maxSkills: 8 // 最大技能数量
            }
        };

        // 简化的SVG图标创建函数
        function createSvgIcon(itemHrid, iconType = null, className = 'Icon_icon__2LtL_') {
            // 自动检测图标类型和提取itemId
            let type = 'items';
            let itemId = itemHrid;
            
            if (itemHrid.startsWith('/items/')) {
                type = 'items';
                itemId = itemHrid.replace('/items/', '');
            } else if (itemHrid.startsWith('/abilities/')) {
                type = 'abilities';
                itemId = itemHrid.replace('/abilities/', '');
            } else if (itemHrid.startsWith('/skills/')) {
                type = 'skills';
                itemId = itemHrid.replace('/skills/', '');
            } else if (itemHrid.startsWith('/misc/')) {
                type = 'misc';
                itemId = itemHrid.replace('/misc/', '');
            } else {
                // 对于基础属性图标
                if (['stamina', 'intelligence', 'attack', 'power', 'defense', 'ranged', 'magic'].includes(itemHrid)) {
                    type = 'skills';
                    itemId = itemHrid;
                } else {
                    itemId = itemHrid.replace("/items/", "").replace("/abilities/", "").replace("/skills/", "").replace("/misc/", "");
                }
            }
            
            // 如果手动指定了类型,使用指定的类型
            if (iconType) {
                type = iconType;
            }
            
            // 使用SVG工具创建图标
            if (state.svgTool && state.svgTool.isLoaded) {
                return state.svgTool.createSVGIcon(itemId, { 
                    className: className, 
                    title: itemId,
                    type: type
                });
            }
            
            // 后备方案
            return state.svgTool.createFallbackIcon(itemId, className, itemId);
        }

        function generateEquipmentPanel(characterObj) {
            // MWI装备槽位映射 - 使用grid位置
            const equipmentSlots = {
                "/item_locations/back": { row: 1, col: 1, name: "背部" },
                "/item_locations/head": { row: 1, col: 2, name: "头部" },
                "/item_locations/main_hand": { row: 2, col: 1, name: "主手" },
                "/item_locations/body": { row: 2, col: 2, name: "身体" },
                "/item_locations/off_hand": { row: 2, col: 3, name: "副手" },
                "/item_locations/hands": { row: 3, col: 1, name: "手部" },
                "/item_locations/legs": { row: 3, col: 2, name: "腿部" },
                "/item_locations/pouch": { row: 3, col: 3, name: "口袋" },
                "/item_locations/feet": { row: 4, col: 2, name: "脚部" },
                "/item_locations/neck": { row: 1, col: 5, name: "项链" },
                "/item_locations/earrings": { row: 2, col: 5, name: "耳环" },
                "/item_locations/ring": { row: 3, col: 5, name: "戒指" },
                "/item_locations/trinket": { row: 4, col: 5, name: "饰品" },
                "/item_locations/two_hand": { row: 2, col: 1, name: "双手" }
            };

            let items = characterObj.equipment || characterObj.characterItems || [];
            const equipmentMap = {};
            let hasTwoHandWeapon = false;

            // 构建装备映射
            items.forEach(item => {
                const slotInfo = equipmentSlots[item.itemLocationHrid];
                if (slotInfo) {
                    equipmentMap[item.itemLocationHrid] = item;
                    if (item.itemLocationHrid === "/item_locations/two_hand") hasTwoHandWeapon = true;
                }
            });

            // 创建MWI风格的装备面板
            let html = '<div class="equipment-panel">';
            html += `<div class="panel-title">${isZH ? '装备' : 'Equipments'}</div>`;
            html += '<div class="EquipmentPanel_playerModel__3LRB6" style="margin-top:40px">';
            
            // 遍历所有装备槽位
            Object.entries(equipmentSlots).forEach(([slotHrid, slotInfo]) => {
                // 如果有双手武器,跳过单手主手槽
                if (hasTwoHandWeapon && slotHrid === "/item_locations/main_hand") {
                    return;
                }

                // 如果没有双手武器,跳过双手槽
                if (!hasTwoHandWeapon && slotHrid === "/item_locations/two_hand") {
                    return;
                }
                
                const item = equipmentMap[slotHrid];
                
                html += `<div style="grid-row-start: ${slotInfo.row}; grid-column-start: ${slotInfo.col};">`;
                html += '<div class="ItemSelector_itemSelector__2eTV6">';
                html += '<div class="ItemSelector_itemContainer__3olqe">';
                html += '<div class="Item_itemContainer__x7kH1">';
                html += '<div>';
                
                if (item) {
                    // 有装备的槽位
                    const itemName = item.itemHrid.replace('/items/', '');
                    const enhancementLevel = item.enhancementLevel || 0;
                    
                    html += '<div class="Item_item__2De2O Item_clickable__3viV6" style="position: relative;">';
                    html += '<div class="Item_iconContainer__5z7j4">';
                    html += createSvgIcon(item.itemHrid, 'items'); // 使用MWI的Icon类
                    html += '</div>';
                    
                    // 强化等级 - 完全按照MWI原生格式
                    if (enhancementLevel > 0) {
                        html += `<div class="Item_enhancementLevel__19g-e enhancementProcessed enhancementLevel_${enhancementLevel}" style="z-index: 9">+${enhancementLevel}</div>`;
                    }
                    
                    html += '</div>';
                } else {
                    // 空装备槽
                    html += '<div class="Item_item__2De2O" style="position: relative; opacity: 0.3;">';
                    html += '<div class="Item_iconContainer__5z7j4">';
                    html += `<div style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #999; font-size: 10px;">${isZH ? '空' : 'Empty'}</div>`;
                    html += '</div>';
                    html += '</div>';
                }
                
                html += '</div>';
                html += '</div>';
                html += '</div>';
                html += '</div>';
                html += '</div>';
            });
            
            html += '</div>'; // EquipmentPanel_playerModel__3LRB6
            html += '</div>'; // equipment-panel
            
            return html;
        }

        // 从页面获取战斗等级
        function calculateCombatLevel(characterObj) {
            try {
                // 获取各项属性等级
                const stamina = characterObj.staminaLevel || 0;
                const intelligence = characterObj.intelligenceLevel || 0;
                const defense = characterObj.defenseLevel || 0;
                const attack = characterObj.attackLevel || 0;
                const power = characterObj.powerLevel || 0;
                const ranged = characterObj.rangedLevel || 0;
                const magic = characterObj.magicLevel || 0;
                
                // 计算公式:战斗等级 = 0.2 * (耐力 + 智力 + 防御) + 0.4 * MAX(0.5 * (攻击 + 力量), 远程, 魔法)
                const baseCombat = 0.2 * (stamina + intelligence + defense);
                const attackPower = 0.5 * (attack + power);
                const maxCombat = Math.max(attackPower, ranged, magic);
                const combatLevel = Math.floor(baseCombat + 0.4 * maxCombat);
                
                return combatLevel;
            } catch (error) {
                console.log('计算战斗等级失败:', error);
                return 0;
            }
        }

        function getCombatLevelFromPage() {
            try {
                // 查找包含战斗等级信息的元素
                const overviewTab = document.querySelector('.SharableProfile_overviewTab__W4dCV');
                if (overviewTab) {
                    // 查找包含"战斗等级:"文本的div元素
                    const combatLevelDiv = Array.from(overviewTab.querySelectorAll('div')).find(div => 
                        div.textContent && div.textContent.includes('战斗等级:')
                    );
                    
                    if (combatLevelDiv) {
                        // 提取数字
                        const match = combatLevelDiv.textContent.match(/战斗等级:\s*(\d+)/);
                        if (match && match[1]) {
                            return parseInt(match[1]);
                        }
                    }
                }
            } catch (error) {
                console.log('获取战斗等级失败:', error);
            }
            return 0;
        }

        function generateAbilityPanel(characterObj) {
            const abilityMapping = [
                { key: "staminaLevel", name: isZH ? "耐力" : "Stamina", icon: "stamina" },
                { key: "intelligenceLevel", name: isZH ? "智力" : "Intelligence", icon: "intelligence" },
                { key: "attackLevel", name: isZH ? "攻击" : "Attack", icon: "attack" },
                { key: "powerLevel", name: isZH ? "力量" : "Power", icon: "power" },
                { key: "defenseLevel", name: isZH ? "防御" : "Defense", icon: "defense" },
                { key: "rangedLevel", name: isZH ? "远程" : "Ranged", icon: "ranged" },
                { key: "magicLevel", name: isZH ? "魔法" : "Magic", icon: "magic" }
            ];

            let html = '<div class="ability-panel">';
            html += `<div class="panel-title">${isZH ? '属性等级' : 'Skills'}</div><div class="ability-list">`;
            
            // 添加战斗等级作为第一行
            const combatLevel = calculateCombatLevel(characterObj);
            html += `<div class="ability-row">
                <div class="ability-icon">
                    <svg role="img" aria-label="combat" class="Icon_icon__2LtL_" width="100%" height="100%">
                        <use href="/static/media/misc_sprite.6b3198dc.svg#combat"></use>
                    </svg>
                </div>
                <span style="flex: 1;">${isZH ? '战斗' : 'Combat'}</span>
                <span class="level">Lv.${combatLevel}</span>
            </div>`;
            
            abilityMapping.forEach(ability => {
                let level = 0;
                if (characterObj[ability.key]) {
                    level = characterObj[ability.key];
                } else if (characterObj.characterSkills) {
                    const skillKey = ability.key.replace('Level', '');
                    const skill = characterObj.characterSkills.find(skill => skill.skillHrid.includes(`/skills/${skillKey}`));
                    level = skill ? skill.level : 0;
                }
                
                html += `<div class="ability-row">
                    <div class="ability-icon">${createSvgIcon(ability.icon, 'skills')}</div>
                    <span style="flex: 1;">${ability.name}</span>
                    <span class="level">Lv.${level}</span>
                </div>`;
            });
            
            return html + '</div></div>';
        }

        function generateSkillPanel(data, isMyCharacter = false) {
            let abilities = data.abilities || data.characterSkills || [];
            
            let combatSkills;
            
            if (isMyCharacter) {
                // 场景2:根据slotNumber筛选和排序
                combatSkills = abilities
                    .filter(ability => ability.abilityHrid && ability.abilityHrid.startsWith("/abilities/"))
                    .filter(ability => ability.slotNumber && ability.slotNumber > 0)
                    .sort((a, b) => a.slotNumber - b.slotNumber); // 按slotNumber升序排列
                
                // 初始化用户选择的技能(如果为空)
                if (state.customSkills.selectedSkills.length === 0) {
                    // 默认显示前5个技能
                    state.customSkills.selectedSkills = combatSkills.slice(0, 5).map(skill => ({
                        abilityHrid: skill.abilityHrid,
                        level: skill.level,
                        slotNumber: skill.slotNumber
                    }));
                }
                
                let html = '<div class="skill-panel">';
                html += `<div class="panel-title">${isZH ? '技能等级' : 'Abilities'}</div>`;
                
                // 使用MWI原生的技能网格容器
                html += '<div class="AbilitiesPanel_abilityGrid__-p-VF">';
                
                // 渲染用户选择的技能(最多8个)
                for (let i = 0; i < state.customSkills.maxSkills; i++) {
                    const selectedSkill = state.customSkills.selectedSkills[i];
                    
                    if (selectedSkill) {
                        // 显示已选择的技能
                        html += '<div>';
                        html += `<div class="Ability_ability__1njrh Ability_clickable__w9HcM skill-slot" data-skill-index="${i}">`;
                        html += '<div class="Ability_iconContainer__3syNQ">';
                        html += createSvgIcon(selectedSkill.abilityHrid, 'abilities');
                        html += '</div>';
                        html += `<div class="Ability_level__1L-do">Lv.${selectedSkill.level}</div>`;
                        html += '</div>';
                        html += '</div>';
                    } else {
                        // 显示空白位置(鼠标悬停时显示虚线边框)
                        html += '<div>';
                        html += `<div class="Ability_ability__1njrh Ability_clickable__w9HcM empty-skill-slot" data-skill-index="${i}">`;
                        html += '</div>';
                        html += '</div>';
                    }
                }
                
                html += '</div>'; // AbilitiesPanel_abilityGrid__-p-VF
                html += '</div>'; // skill-panel
                
                return html;
            } else {
                // 场景1:保持原始顺序,不排序
                combatSkills = abilities
                    .filter(ability => ability.abilityHrid && ability.abilityHrid.startsWith("/abilities/"));
                
                let html = '<div class="skill-panel">';
                html += `<div class="panel-title">${isZH ? '技能等级' : 'Abilities'}</div>`;
                
                // 使用MWI原生的技能网格容器
                html += '<div class="AbilitiesPanel_abilityGrid__-p-VF">';
                
                // 渲染每个技能
                combatSkills.forEach(ability => {
                    const abilityId = ability.abilityHrid.replace('/abilities/', '');
                    
                    html += '<div>';
                    html += '<div class="Ability_ability__1njrh Ability_clickable__w9HcM">';
                    html += '<div class="Ability_iconContainer__3syNQ">';
                    html += createSvgIcon(ability.abilityHrid, 'abilities'); // 使用完整的hrid
                    html += '</div>';
                    html += `<div class="Ability_level__1L-do">Lv.${ability.level}</div>`;
                    html += '</div>';
                    html += '</div>';
                });
                
                html += '</div>'; // AbilitiesPanel_abilityGrid__-p-VF
                html += '</div>'; // skill-panel
                
                return html;
            }
        }

        function generateHousePanel(data) {
            const houseRoomsMapping = [
                { hrid: "/house_rooms/dining_room", icon: "stamina", name: isZH ? "餐厅" : "Dining Room" },
                { hrid: "/house_rooms/library", icon: "intelligence", name: isZH ? "图书馆" : "Library" },
                { hrid: "/house_rooms/dojo", icon: "attack", name: isZH ? "道场" : "Dojo" },
                { hrid: "/house_rooms/gym", icon: "power", name: isZH ? "健身房" : "Gym" },
                { hrid: "/house_rooms/armory", icon: "defense", name: isZH ? "军械库" : "Armory" },
                { hrid: "/house_rooms/archery_range", icon: "ranged", name: isZH ? "射箭场" : "Archery Range" },
                { hrid: "/house_rooms/mystical_study", icon: "magic", name: isZH ? "神秘研究室" : "Mystical Study" }
            ];

            let houseRoomMap = data.houseRooms || data.characterHouseRoomMap || {};

            let html = '<div class="house-panel">';
            html += `<div class="panel-title">${isZH ? '房屋等级' : 'House Rooms'}</div>`;
            
            // 使用和技能面板相同的MWI原生结构
            html += '<div class="AbilitiesPanel_abilityGrid__-p-VF">';
            
            // 遍历所有房屋类型
            houseRoomsMapping.forEach(houseRoom => {
                let level = 0;
                if (houseRoomMap[houseRoom.hrid]) {
                    level = typeof houseRoomMap[houseRoom.hrid] === 'object' 
                        ? houseRoomMap[houseRoom.hrid].level || 0 
                        : houseRoomMap[houseRoom.hrid];
                }
                
                // 使用和技能相同的MWI原生结构
                html += '<div>';
                html += '<div class="Ability_ability__1njrh Ability_clickable__w9HcM">';
                html += '<div class="Ability_iconContainer__3syNQ">';
                html += createSvgIcon(houseRoom.icon, 'skills'); // 使用标准的Icon类
                html += '</div>';
                // 为8级房屋添加特殊显示
                let levelText = '';
                let levelClass = 'Ability_level__1L-do';
                
                if (level === 8) {
                    levelText = `Lv.8`;
                    levelClass += ' house-max-level';
                } else if (level > 0) {
                    levelText = `Lv.${level}`;
                } else {
                    levelText = isZH ? '未建造' : 'Lv.0';
                }
                
                html += `<div class="${levelClass}">${levelText}</div>`;
                html += '</div>';
                html += '</div>';
            });
            
            html += '</div>'; // AbilitiesPanel_abilityGrid__-p-VF
            html += '</div>'; // house-panel
            
            return html;
        }

        function generateCharacterCard(data, characterName, characterNameElement = null, isMyCharacter = false) {
            let characterObj = data.player || data;
            const equipmentPanel = generateEquipmentPanel(characterObj);
            
            // 创建标题栏内容
            let headerContent = '';
            if (characterNameElement) {
                // 使用从页面复制的角色信息元素
                headerContent = characterNameElement;
            } else {
                // 后备方案:使用简单的角色名
                headerContent = `<h2>${characterName}</h2>`;
            }
            
            return `
                <div id="character-card" class="character-card">
                    <div class="card-header">${headerContent}</div>
                    <div class="card-content">
                        ${equipmentPanel}
                        ${generateAbilityPanel(characterObj)}
                        ${generateSkillPanel(data, isMyCharacter)}
                        ${generateHousePanel(data)}
                    </div>
                </div>
            `;
        }

        function createModalStyles() {
            const style = document.createElement('style');
            style.textContent = `
                .character-card-modal {
                    position: fixed; top: 0; left: 0; width: 100%; height: 100%;
                    background: rgba(0, 0, 0, 0.8); z-index: 10000; display: flex;
                    justify-content: center; align-items: center; padding: 16px; box-sizing: border-box;
                }
                .modal-content {
                    background: white; border-radius: 15px; padding: 20px;
                    max-width: 90vw; max-height: 90vh; overflow: auto; position: relative;
                }
                .close-modal {
                    position: absolute; top: 10px; right: 15px; background: none;
                    border: none; font-size: 24px; cursor: pointer; color: #666; z-index: 1;
                }
                .close-modal:hover { color: #000; }
                .character-card {
                    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
                    border: 2px solid #4a90e2; border-radius: 15px; padding: 20px; color: white;
                    font-family: 'Arial', sans-serif; max-width: 800px; margin: 0 auto;
                    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
                }
                .card-header {
                    text-align: center; margin-bottom: 20px; border-bottom: 2px solid #4a90e2; padding-bottom: 10px;
                }
                .card-header h2 {
                    margin: 0; color: #4a90e2; font-size: 24px; text-shadow: 0 0 10px rgba(74, 144, 226, 0.5);
                }
                
                /* 角色信息元素在名片中的样式 */
                .card-header .CharacterName_characterName__2FqyZ {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    flex-wrap: wrap;
                    gap: 8px;
                }
                
                .card-header .CharacterName_chatIcon__22lxV {
                    width: 32px;
                    height: 32px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }
                
                .card-header .CharacterName_name__1amXp {
                    font-size: 20px;
                    font-weight: bold;
                    text-shadow: 0 0 10px rgba(74, 144, 226, 0.5);
                }
                
                .card-header .CharacterName_gameMode__2Pvw8 {
                    font-size: 14px;
                    opacity: 0.8;
                }
                .card-content {
                    display: grid; grid-template-columns: 1fr 0.7fr; grid-template-rows: auto 1fr; gap: 20px;
                }
                .equipment-panel, .house-panel, .ability-panel, .skill-panel {
                    background: rgba(255, 255, 255, 0.1); border-radius: 10px; padding: 6px;
                    border: 1px solid rgba(74, 144, 226, 0.3);
                }
                .panel-title {
                    margin: 0 0 15px 0; color: #4a90e2; font-size: 16px;
                    border-bottom: 1px solid rgba(74, 144, 226, 0.3); padding-bottom: 5px; text-align: center;
                }
                .equipment-panel { grid-column: 1; grid-row: 1; }
                
                /* 只为模态框内的装备面板添加网格布局,不影响游戏原生UI */
                .character-card .EquipmentPanel_playerModel__3LRB6 {
                    display: grid;
                    grid-template-columns: repeat(5, 1fr);
                    grid-template-rows: repeat(4, auto);
                    gap: 8px;
                    padding: 10px;
                    max-width: 350px;
                    margin: 0 auto;
                }
                
                /* 确保装备槽的基本布局 */
                .character-card .ItemSelector_itemSelector__2eTV6 {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    min-height: 60px;
                }
                
                /* 技能面板样式 - 仅作用于角色名片内 */
                .character-card .AbilitiesPanel_abilityGrid__-p-VF {
                    display: grid;
                    grid-template-columns: repeat(4, 1fr);
                    gap: 8px;
                    padding: 10px;
                    max-height: 180px;
                    overflow-y: auto;
                }
                
                /* 技能项容器 */
                .character-card .Ability_ability__1njrh {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;
                    min-height: 70px;
                    border-radius: 8px;
                    background: rgba(255, 255, 255, 0.05);
                    border: 1px solid rgba(74, 144, 226, 0.3);
                    transition: all 0.2s ease;
                }
                
                .character-card .Ability_ability__1njrh.Ability_clickable__w9HcM:hover {
                    background: rgba(74, 144, 226, 0.1);
                    border-color: #4a90e2;
                    transform: scale(1.05);
                }
                
                /* 技能图标容器 */
                .character-card .Ability_iconContainer__3syNQ {
                    width: 36px;
                    height: 36px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    margin-bottom: 4px;
                }
                
                /* 房屋等级图标容器 - 调整垂直居中 */
                .character-card .house-panel .Ability_iconContainer__3syNQ {
                    width: 36px;
                    height: 36px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    margin-bottom: 4px;
                    transform: translateY(2px);
                }
                
                /* 技能等级文字 */
                .character-card .Ability_level__1L-do {
                    font-size: 12px;
                    font-weight: bold;
                    color: #fff;
                    text-align: center;
                }
                
                /* 房屋最高等级特殊样式 */
                .character-card .house-max-level {
                    color: #ff8c00 !important;
                    font-weight: bold;
                    text-shadow: 0 0 4px rgba(255, 140, 0, 0.5);
                }
                .ability-panel { grid-column: 2; grid-row: 1; }
                .ability-list { flex: 1; }
                .ability-row {
                    display: flex; align-items: center; margin-bottom: 8px; padding: 4px; border-radius: 4px;
                }
                .ability-icon {
                    width: 30px; height: 30px; margin-right: 10px; display: flex;
                    align-items: center; justify-content: center;
                }
                .house-panel { 
                    grid-column: 1; 
                    grid-row: 2; 
                }
                

                .skill-panel { 
                    grid-column: 2; 
                    grid-row: 2; 
                }
                .level { color: #fff; font-weight: bold; }
                @media (max-width: 768px) {
                    /* 移动端模态框调整 */
                    .character-card-modal {
                        padding: 8px;
                    }
                    
                    .modal-content {
                        max-width: 95vw;
                        max-height: 95vh;
                        padding: 12px;
                        overflow-y: auto;
                    }
                    
                    /* 移动端单列布局 */
                    .card-content { 
                        grid-template-columns: 1fr; 
                        grid-template-rows: auto auto auto auto; 
                        gap: 12px;
                    }
                    
                    .equipment-panel { grid-column: 1; grid-row: 1; }
                    .ability-panel { grid-column: 1; grid-row: 2; }
                    .house-panel { grid-column: 1; grid-row: 3; }
                    .skill-panel { grid-column: 1; grid-row: 4; }
                    
                    /* 移动端面板样式调整 */
                    .equipment-panel, .house-panel, .ability-panel, .skill-panel {
                        padding: 10px;
                        margin-bottom: 4px;
                    }
                    
                    /* 移动端装备面板调整 - 保持游戏原始布局 */
                    .character-card .EquipmentPanel_playerModel__3LRB6 {
                        gap: 6px;
                        padding: 8px;
                        max-width: 100%;
                    }
                    
                    /* 移动端技能面板调整 - 每行4个 */
                    .character-card .ability-panel .AbilitiesPanel_abilityGrid__-p-VF {
                        grid-template-columns: repeat(4, 1fr);
                        gap: 10px;
                        padding: 12px;
                        max-height: 180px;
                    }
                    
                    /* 移动端房屋面板调整 - 每行4个 */
                    .character-card .house-panel .AbilitiesPanel_abilityGrid__-p-VF {
                        grid-template-columns: repeat(4, 1fr);
                        gap: 8px;
                        padding: 10px;
                        max-height: 180px;
                    }
                    
                    /* 移动端技能卡片间距调整 */
                    .character-card .ability-panel .Ability_ability__1njrh {
                        margin: 2px;
                        min-height: 75px;
                    }
                    
                    /* 移动端房屋卡片间距调整 - 4列布局 */
                    .character-card .house-panel .Ability_ability__1njrh {
                        margin: 1px;
                        min-height: 65px;
                        font-size: 11px;
                    }
                    
                    /* 移动端房屋等级图标容器 - 调整垂直居中 */
                    .character-card .house-panel .Ability_iconContainer__3syNQ {
                        transform: translateY(1px);
                    }
                    
                    /* 移动端面板标题调整 */
                    .panel-title {
                        font-size: 14px;
                        margin-bottom: 8px;
                        padding-bottom: 4px;
                    }
                    
                    /* 移动端字体调整 */
                    .character-card {
                        font-size: 12px;
                    }
                    
                    /* 移动端指示横幅调整 */
                    .instruction-banner {
                        padding: 8px;
                        font-size: 14px;
                    }
                }
                
                .instruction-banner {
                    background: #17a2b8; color: white; padding: 10px; border-radius: 5px;
                    margin-bottom: 10px; font-weight: bold; text-align: center;
                }
                
                .download-section {
                    text-align: center; margin-bottom: 15px;
                }
                
                .download-card-btn {
                    background: #17a2b8;
                    color: white;
                    border: none;
                    padding: 6px 12px;
                    border-radius: 4px;
                    font-size: 12px;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                }
                
                .download-card-btn:hover:not(:disabled) {
                    background: #138496;
                    transform: translateY(-1px);
                    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
                }
                
                .download-card-btn:disabled {
                    background: #6c757d; cursor: not-allowed; transform: none;
                    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                }
                
                /* 技能提示样式 */
                .skill-hint {
                    margin-top: 8px;
                    text-align: center;
                }
                
                .skill-hint span {
                    font-size: 12px;
                    color: #17a2b8;
                    font-style: italic;
                    background: rgba(23, 162, 184, 0.1);
                    padding: 4px 8px;
                    border-radius: 4px;
                    border: 1px solid rgba(23, 162, 184, 0.3);
                }
                
                /* 按钮行样式 */
                .button-row {
                    display: flex;
                    gap: 8px;
                    justify-content: center;
                    align-items: center;
                    margin-bottom: 8px;
                }
                
                .save-skill-config-btn,
                .load-skill-config-btn {
                    background: #17a2b8;
                    color: white;
                    border: none;
                    padding: 6px 12px;
                    border-radius: 4px;
                    font-size: 12px;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                }
                
                .save-skill-config-btn:hover,
                .load-skill-config-btn:hover {
                    background: #138496;
                    transform: translateY(-1px);
                    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
                }
                

                
                /* 仅为角色名片内的SVG图标添加优化,不影响游戏原生UI */
                .character-card .Icon_icon__2LtL_ {
                    width: 100%;
                    height: 100%;
                    filter: drop-shadow(0 0 2px rgba(0,0,0,0.3));
                    image-rendering: -webkit-optimize-contrast;
                    image-rendering: -moz-crisp-edges;
                    image-rendering: pixelated;
                }
                
                /* 空白技能槽样式 */
                .character-card .empty-skill-slot {
                    cursor: pointer;
                    border: 1px dashed rgba(74, 144, 226, 0.3);
                    background: transparent;
                    min-height: 70px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }
                
                .character-card .empty-skill-slot:hover {
                    border: 1px dashed #4a90e2;
                    background: rgba(74, 144, 226, 0.1);
                }
                
                /* 技能选择器模态框样式 */
                .skill-selector-modal {
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    background: rgba(0, 0, 0, 0.8);
                    z-index: 20000;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding: 16px;
                    box-sizing: border-box;
                }
                
                .skill-selector-content {
                    background: #1a1a2e;
                    border-radius: 15px;
                    padding: 20px;
                    max-width: 80vw;
                    max-height: 80vh;
                    overflow: auto;
                    position: relative;
                    min-width: 400px;
                    border: 2px solid #4a90e2;
                }
                
                .skill-selector-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 20px;
                    border-bottom: 1px solid #4a90e2;
                    padding-bottom: 10px;
                }
                
                .skill-selector-header h3 {
                    margin: 0;
                    color: #fff;
                    font-size: 18px;
                }
                
                .close-skill-selector {
                    background: none;
                    border: none;
                    font-size: 24px;
                    cursor: pointer;
                    color: #ccc;
                    padding: 0;
                    width: 30px;
                    height: 30px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }
                
                .close-skill-selector:hover {
                    color: #fff;
                }
                
                .skill-selector-grid {
                    display: grid;
                    grid-template-columns: repeat(4, 1fr);
                    gap: 12px;
                    max-height: 400px;
                    overflow-y: auto;
                }
                
                .skill-option {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    padding: 8px;
                    border: 1px solid #4a90e2;
                    border-radius: 8px;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    background: rgba(255, 255, 255, 0.05);
                }
                
                .skill-option:hover {
                    border-color: #4a90e2;
                    background: rgba(74, 144, 226, 0.2);
                    transform: scale(1.05);
                }
                
                .skill-option-icon {
                    width: 40px;
                    height: 40px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    margin-bottom: 4px;
                }
                
                .skill-option-level {
                    font-size: 11px;
                    font-weight: bold;
                    color: #fff;
                    text-align: center;
                }
                
                /* 空技能选项样式 */
                .skill-option.empty-skill-option {
                    border: 1px dashed #4a90e2;
                    background: rgba(255, 255, 255, 0.02);
                }
                
                .skill-option.empty-skill-option:hover {
                    border-color: #4a90e2;
                    background: rgba(74, 144, 226, 0.1);
                }
                
                .empty-skill-icon {
                    width: 40px;
                    height: 40px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border: 1px dashed #4a90e2;
                    border-radius: 4px;
                    color: #4a90e2;
                    font-size: 16px;
                    font-weight: bold;
                }
                

                
                /* 移动端技能选择器调整 */
                @media (max-width: 768px) {
                    .skill-selector-content {
                        max-width: 95vw;
                        min-width: 300px;
                        padding: 15px;
                    }
                    
                    .skill-selector-grid {
                        grid-template-columns: repeat(4, 1fr);
                        gap: 8px;
                    }
                    
                    .skill-option {
                        padding: 6px;
                    }
                    
                    .skill-option-icon {
                        width: 32px;
                        height: 32px;
                    }
                    
                    .skill-option-level {
                        font-size: 10px;
                    }
                    
                    .empty-skill-icon {
                        width: 32px;
                        height: 32px;
                        font-size: 14px;
                    }
                }
            `;
            document.head.appendChild(style);
        }

        async function readClipboardData() {
            try {
                const text = await navigator.clipboard.readText();
                return text;
            } catch (error) {
                console.log('无法读取剪贴板:', error);
                return null;
            }
        }

        function isValidCharacterData(data) {
            if (!data || typeof data !== 'object') return false;
            
            // 检查新格式 (player对象)
            if (data.player && (
                data.player.equipment || 
                data.player.characterItems || 
                data.player.staminaLevel !== undefined ||
                data.player.name
            )) {
                return true;
            }
            
            // 检查旧格式
            if (data.character && (data.characterSkills || data.characterItems)) {
                return true;
            }
            
            // 检查是否直接包含关键字段
            if (data.equipment || data.characterItems || data.characterSkills) {
                return true;
            }
            
            // 检查是否包含技能等级字段
            if (data.staminaLevel !== undefined || data.intelligenceLevel !== undefined || 
                data.attackLevel !== undefined || data.powerLevel !== undefined) {
                return true;
            }
            
            // 检查是否包含房屋数据
            if (data.houseRooms || data.characterHouseRoomMap) {
                return true;
            }
            
            // 检查是否包含能力数据
            if (data.abilities && Array.isArray(data.abilities)) {
                return true;
            }
            
            return false;
        }

        // 获取SVG sprite内容
        async function loadSpriteContent(spriteUrl) {
            try {
                const response = await fetch(spriteUrl);
                const svgText = await response.text();
                const parser = new DOMParser();
                const svgDoc = parser.parseFromString(svgText, 'image/svg+xml');
                return svgDoc.documentElement;
            } catch (error) {
                console.warn('无法加载sprite:', spriteUrl, error);
                return null;
            }
        }

        // 下载名片功能
        async function downloadCharacterCard() {
            try {
                // 获取名片元素
                const cardElement = document.getElementById('character-card');
                if (!cardElement) {
                    alert(isZH ? '未找到名片元素' : 'Character card element not found');
                    return;
                }

                // 显示下载提示
                const downloadBtn = document.querySelector('.download-card-btn');
                const originalText = downloadBtn.textContent;
                downloadBtn.textContent = isZH ? '生成中...' : 'Generating...';
                downloadBtn.disabled = true;

                // 克隆名片元素用于处理
                const clonedCard = cardElement.cloneNode(true);
                
                // 如果是场景2(我的角色名片),重新生成技能面板以保持自定义技能状态
                const isMyCharacterCard = cardElement.querySelector('.skill-panel .empty-skill-slot') !== null;
                if (isMyCharacterCard && state.customSkills.selectedSkills.length > 0) {
                    const skillPanel = clonedCard.querySelector('.skill-panel');
                    if (skillPanel) {
                        const characterData = {
                            abilities: window.characterCardWebSocketData?.characterAbilities || [],
                            characterSkills: window.characterCardWebSocketData?.characterSkills || []
                        };
                        const newSkillPanel = generateSkillPanel(characterData, true);
                        skillPanel.innerHTML = newSkillPanel.replace(/<div class="skill-panel">([\s\S]*?)<\/div>$/, '$1');
                    }
                }
                
                // 预加载所有sprite内容
                const spriteContents = {};
                const spriteUrls = Object.values(state.svgTool.spriteSheets);
                
                // 检查是否需要加载聊天图标sprite
                const needsChatSprite = clonedCard.querySelector('svg use[href*="chat_icons_sprite"]');
                if (needsChatSprite) {
                    spriteUrls.push('/static/media/chat_icons_sprite.2a8f0be2.svg');
                }
                
                for (const url of spriteUrls) {
                    const content = await loadSpriteContent(url);
                    if (content) {
                        spriteContents[url] = content;
                    }
                }



                // 替换所有使用<use>的SVG为实际内容
                const useElements = clonedCard.querySelectorAll('svg use');
                
                useElements.forEach((useElement, index) => {
                    try {
                        const href = useElement.getAttribute('href');
                        const svg = useElement.closest('svg');
                        
                        if (href && href.includes('#')) {
                            const [spriteUrl, symbolId] = href.split('#');
                            const spriteContent = spriteContents[spriteUrl];
                            
                            if (spriteContent && symbolId) {
                                const symbol = spriteContent.querySelector(`#${symbolId}`);
                                if (symbol) {
                                    // 创建新的SVG内容
                                    const svg = useElement.closest('svg');
                                    if (svg) {
                                        const symbolClone = symbol.cloneNode(true);
                                        
                                        // 清空原SVG内容并添加symbol内容
                                        svg.innerHTML = '';
                                        
                                        // 添加fill="none"属性解决填充问题
                                        svg.setAttribute('fill', 'none');
                                        
                                        // 如果symbol有viewBox,应用到svg
                                        const viewBox = symbol.getAttribute('viewBox');
                                        if (viewBox) {
                                            svg.setAttribute('viewBox', viewBox);
                                        }
                                        
                                        // 复制symbol的所有子元素到svg
                                        while (symbolClone.firstChild) {
                                            svg.appendChild(symbolClone.firstChild);
                                        }
                                    }
                                } else {
                                    // 如果找不到symbol,创建文字替代
                                    const svg = useElement.closest('svg');
                                    if (svg) {
                                        svg.innerHTML = `<text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" fill="white" font-size="10">${symbolId.substring(0, 3)}</text>`;
                                    }
                                }
                            } else {
                                // 如果找不到spriteContent,创建简单替代
                                const svg = useElement.closest('svg');
                                if (svg && symbolId) {
                                    const shortText = symbolId.length > 2 ? symbolId.substring(0, 2) : symbolId;
                                    svg.innerHTML = `<text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" fill="white" font-size="8">${shortText}</text>`;
                                }
                            }
                        }
                    } catch (error) {
                        console.warn('处理SVG元素时出错:', error);
                    }
                });
                
                // 简单处理角色名 - 移除上级div的class使其显示为白色
                const characterNameDiv = clonedCard.querySelector('.CharacterName_name__1amXp');
                if (characterNameDiv) {
                    characterNameDiv.className = ''; // 清除所有class,使角色名显示为白色
                }

                // 检测是否为移动端设备
                const isMobileDevice = isMobile();
                
                // 内联关键样式(避免linear-gradient问题)
                const styleElement = document.createElement('style');
                
                // 根据设备类型选择不同的样式
                if (isMobileDevice) {
                    // 移动端样式 - 单列布局
                    styleElement.textContent = `
                        .character-card {
                            background: #1a1a2e !important;
                            border: 2px solid #4a90e2 !important;
                            border-radius: 15px !important;
                            padding: 15px !important;
                            color: white !important;
                            font-family: Arial, sans-serif !important;
                            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5) !important;
                            max-width: 100% !important;
                            width: 350px !important;
                        }
                        .card-header {
                            text-align: center !important;
                            margin-bottom: 15px !important;
                            border-bottom: 2px solid #4a90e2 !important;
                            padding-bottom: 8px !important;
                        }
                        .card-content {
                            display: grid !important;
                            grid-template-columns: 1fr !important;
                            grid-template-rows: auto auto auto auto !important;
                            gap: 15px !important;
                        }
                        .equipment-panel { grid-column: 1 !important; grid-row: 1 !important; }
                        .ability-panel { grid-column: 1 !important; grid-row: 2 !important; }
                        .house-panel { grid-column: 1 !important; grid-row: 3 !important; }
                        .skill-panel { grid-column: 1 !important; grid-row: 4 !important; }
                        .equipment-panel, .house-panel, .ability-panel, .skill-panel {
                            background: rgba(255, 255, 255, 0.1) !important;
                            border-radius: 10px !important;
                            padding: 10px !important;
                            margin-bottom: 4px !important;
                            border: 1px solid rgba(74, 144, 226, 0.3) !important;
                        }
                        .panel-title {
                            margin: 0 0 10px 0 !important;
                            color: #4a90e2 !important;
                            font-size: 14px !important;
                            border-bottom: 1px solid rgba(74, 144, 226, 0.3) !important;
                            padding-bottom: 4px !important;
                            text-align: center !important;
                        }
                        .EquipmentPanel_playerModel__3LRB6 {
                            display: grid !important;
                            grid-template-columns: repeat(5, 1fr) !important;
                            grid-template-rows: repeat(4, auto) !important;
                            gap: 6px !important;
                            padding: 8px !important;
                            max-width: 100% !important;
                            margin: 0 auto !important;
                        }
                        /* 技能面板 - 每行4个 */
                        .ability-panel .AbilitiesPanel_abilityGrid__-p-VF {
                            display: grid !important;
                            grid-template-columns: repeat(4, 1fr) !important;
                            gap: 10px !important;
                            padding: 12px !important;
                            max-height: 180px !important;
                            overflow-y: auto !important;
                        }
                        
                        /* 房屋面板 - 每行4个 */
                        .house-panel .AbilitiesPanel_abilityGrid__-p-VF {
                            display: grid !important;
                            grid-template-columns: repeat(4, 1fr) !important;
                            gap: 8px !important;
                            padding: 10px !important;
                            max-height: 180px !important;
                            overflow-y: auto !important;
                        }
                        /* 技能卡片样式 */
                        .ability-panel .Ability_ability__1njrh {
                            margin: 2px !important;
                            min-height: 75px !important;
                        }
                        
                        /* 房屋卡片样式 - 4列布局 */
                        .house-panel .Ability_ability__1njrh {
                            margin: 1px !important;
                            min-height: 65px !important;
                            font-size: 11px !important;
                        }
                        .level { color: #fff !important; font-weight: bold !important; font-size: 12px !important; }
                        svg { width: 100% !important; height: 100% !important; }
                    `;
                } else {
                    // 桌面端样式 - 双列布局
                    styleElement.textContent = `
                        .character-card {
                            background: #1a1a2e !important;
                            border: 2px solid #4a90e2 !important;
                            border-radius: 15px !important;
                            padding: 20px !important;
                            color: white !important;
                            font-family: Arial, sans-serif !important;
                            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5) !important;
                        }
                        .card-header {
                            text-align: center !important;
                            margin-bottom: 20px !important;
                            border-bottom: 2px solid #4a90e2 !important;
                            padding-bottom: 10px !important;
                        }
                        .card-content {
                            display: grid !important;
                            grid-template-columns: 1fr 0.7fr !important;
                            grid-template-rows: auto 1fr !important;
                            gap: 20px !important;
                        }
                        .equipment-panel { grid-column: 1 !important; grid-row: 1 !important; }
                        .ability-panel { grid-column: 2 !important; grid-row: 1 !important; }
                        .house-panel { grid-column: 1 !important; grid-row: 2 !important; }
                        .skill-panel { grid-column: 2 !important; grid-row: 2 !important; }
                        .equipment-panel, .house-panel, .ability-panel, .skill-panel {
                            background: rgba(255, 255, 255, 0.1) !important;
                            border-radius: 10px !important;
                            padding: 15px !important;
                            border: 1px solid rgba(74, 144, 226, 0.3) !important;
                        }
                        .panel-title {
                            margin: 0 0 15px 0 !important;
                            color: #4a90e2 !important;
                            font-size: 16px !important;
                            border-bottom: 1px solid rgba(74, 144, 226, 0.3) !important;
                            padding-bottom: 5px !important;
                            text-align: center !important;
                        }
                        .EquipmentPanel_playerModel__3LRB6 {
                            display: grid !important;
                            grid-template-columns: repeat(5, 1fr) !important;
                            grid-template-rows: repeat(4, auto) !important;
                            gap: 8px !important;
                            padding: 10px !important;
                            max-width: 350px !important;
                            margin: 0 auto !important;
                        }
                        .AbilitiesPanel_abilityGrid__-p-VF {
                            display: grid !important;
                            grid-template-columns: repeat(4, 1fr) !important;
                            gap: 8px !important;
                            padding: 10px !important;
                            max-height: 180px !important;
                            overflow-y: auto !important;
                        }
                        .level { color: #fff !important; font-weight: bold !important; }
                        svg { width: 100% !important; height: 100% !important; }
                    `;
                }
                clonedCard.insertBefore(styleElement, clonedCard.firstChild);
                

                
                // 创建临时容器
                const tempContainer = document.createElement('div');
                tempContainer.style.position = 'absolute';
                tempContainer.style.left = '-9999px';
                tempContainer.style.top = '-9999px';
                tempContainer.appendChild(clonedCard);
                document.body.appendChild(tempContainer);

                // 配置html2canvas选项(根据设备类型调整)
                const options = {
                    backgroundColor: '#1a1a2e', // 使用纯色背景代替渐变
                    scale: isMobileDevice ? 1.5 : 2, // 移动端使用较小的缩放比例
                    useCORS: true,
                    allowTaint: true,
                    foreignObjectRendering: false,
                    width: isMobileDevice ? 350 : cardElement.offsetWidth, // 移动端使用固定宽度
                    height: isMobileDevice ? undefined : cardElement.offsetHeight, // 移动端自动计算高度
                    logging: false, // 关闭日志减少干扰
                    onclone: function(clonedDoc) {
                        try {
                            // 在克隆的文档中应用样式修复
                            const clonedCard = clonedDoc.querySelector('#character-card');
                            if (clonedCard) {
                                if (isMobileDevice) {
                                    // 移动端样式修复
                                    clonedCard.style.background = '#1a1a2e';
                                    clonedCard.style.border = '2px solid #4a90e2';
                                    clonedCard.style.borderRadius = '15px';
                                    clonedCard.style.padding = '15px';
                                    clonedCard.style.color = 'white';
                                    clonedCard.style.fontFamily = 'Arial, sans-serif';
                                    clonedCard.style.width = '350px';
                                    clonedCard.style.maxWidth = '100%';
                                } else {
                                    // 桌面端样式修复
                                    clonedCard.style.background = '#1a1a2e';
                                    clonedCard.style.border = '2px solid #4a90e2';
                                    clonedCard.style.borderRadius = '15px';
                                    clonedCard.style.padding = '20px';
                                    clonedCard.style.color = 'white';
                                    clonedCard.style.fontFamily = 'Arial, sans-serif';
                                }
                                
                                // 确保所有文本都是白色
                                const allText = clonedCard.querySelectorAll('*');
                                allText.forEach(el => {
                                    if (el.tagName !== 'SVG' && el.tagName !== 'USE') {
                                        el.style.color = 'white';
                                    }
                                });
                            }
                        } catch (error) {
                            console.warn('处理克隆文档时出错:', error);
                        }
                    }
                };

                // 生成画布
                const canvas = await html2canvas(clonedCard, options);
                
                // 清理临时容器
                document.body.removeChild(tempContainer);
                
                // 检查画布是否有内容
                const ctx = canvas.getContext('2d');
                const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                const data = imageData.data;
                let hasContent = false;
                
                // 检查是否有非透明像素
                for (let i = 3; i < data.length; i += 4) {
                    if (data[i] > 0) {
                        hasContent = true;
                        break;
                    }
                }
                
                if (!hasContent) {
                    console.warn('主要下载方法生成的图片为空,尝试备用方法...');
                    // 使用更简单的方法重试
                    const simpleOptions = {
                        backgroundColor: '#1a1a2e',
                        scale: 1,
                        useCORS: false,
                        allowTaint: true,
                        logging: false,
                        width: cardElement.offsetWidth,
                        height: cardElement.offsetHeight
                    };
                    
                    const simpleCanvas = await html2canvas(cardElement, simpleOptions);
                    const simpleCtx = simpleCanvas.getContext('2d');
                    const simpleImageData = simpleCtx.getImageData(0, 0, simpleCanvas.width, simpleCanvas.height);
                    const simpleData = simpleImageData.data;
                    let simpleHasContent = false;
                    
                    // 检查备用方法是否有内容
                    for (let i = 3; i < simpleData.length; i += 4) {
                        if (simpleData[i] > 0) {
                            simpleHasContent = true;
                            break;
                        }
                    }
                    
                    if (simpleHasContent) {
                        // 备用方法成功,使用备用画布
                        const link = document.createElement('a');
                        link.download = `MWI_Character_Card_${new Date().getTime()}.png`;
                        link.href = simpleCanvas.toDataURL('image/png', 1.0);
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                        
                        // 清理并恢复按钮状态
                        document.body.removeChild(tempContainer);
                        downloadBtn.textContent = originalText;
                        downloadBtn.disabled = false;
                        console.log('使用备用方法成功生成名片图片');
                        return;
                    } else {
                        throw new Error('生成的图片没有内容(主要方法和备用方法都失败)');
                    }
                }
                
                // 创建下载链接
                const link = document.createElement('a');
                link.download = `MWI_Character_Card_${new Date().getTime()}.png`;
                link.href = canvas.toDataURL('image/png', 1.0);
                
                // 触发下载
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);

                // 恢复按钮状态
                downloadBtn.textContent = originalText;
                downloadBtn.disabled = false;
                
                console.log('名片图片已生成并下载');
                
            } catch (error) {
                console.error('下载名片失败:', error);
                alert(isZH ? 
                    '下载名片失败\n\n错误信息: ' + error.message + '\n\n建议:请确保网络连接正常,并允许浏览器下载文件' : 
                    'Failed to download character card\n\nError: ' + error.message + '\n\nSuggestion: Please ensure network connection and allow browser downloads');
                
                // 恢复按钮状态
                const downloadBtn = document.querySelector('.download-card-btn');
                if (downloadBtn) {
                    downloadBtn.textContent = isZH ? '下载名片' : 'Download Card';
                    downloadBtn.disabled = false;
                }
            }
        }



        // 自动点击导出按钮的辅助函数
        async function autoClickExportButton() {
            try {
                console.log('尝试自动点击导出按钮...');
                
                // 查找导出按钮的多种可能选择器
                const exportButtonSelectors = [
                    // 中文版本的按钮文本
                    'button:contains("导出人物到剪贴板")',
                    // 英文版本的按钮文本
                    'button:contains("Export to clipboard")',
                ];
                
                let exportButton = null;
                
                // 尝试通过按钮文本查找(中文和英文)
                const allButtons = document.querySelectorAll('button');
                for (const button of allButtons) {
                    const buttonText = button.textContent.trim();
                    if (buttonText.includes('导出人物到剪贴板') || 
                        buttonText.includes('Export to clipboard')) {
                        exportButton = button;
                        break;
                    }
                }
                
                // 如果通过文本没找到,尝试其他属性
                if (!exportButton) {
                    for (const selector of exportButtonSelectors.slice(4)) { // 跳过contains选择器
                        try {
                            exportButton = document.querySelector(selector);
                            if (exportButton) {
                                console.log('通过选择器找到导出按钮:', selector);
                                break;
                            }
                        } catch (e) {
                            // 忽略选择器错误
                        }
                    }
                }
                
                if (!exportButton) {
                    console.log('未找到导出按钮,将直接尝试读取剪贴板');
                    return false;
                }
                
                // 检查按钮是否可点击
                if (exportButton.disabled || exportButton.style.display === 'none') {
                    console.log('导出按钮不可用,将直接尝试读取剪贴板');
                    return false;
                }
                
                // 点击按钮
                exportButton.click();
                console.log('已点击导出按钮,等待数据导出...');
                
                // 等待一段时间让数据导出到剪贴板
                await new Promise(resolve => setTimeout(resolve, 500));
                
                return true;
            } catch (error) {
                console.log('自动点击导出按钮失败:', error);
                return false;
            }
        }

        // 使用剪贴板数据生成名片(用于查看其他角色)
        async function showCharacterCard() {
            try {
                let characterData = null;
                let dataSource = isZH ? `剪贴板数据` : `Clipboard Data`;
                
                // 先尝试自动点击导出按钮
                const autoExportSuccess = await autoClickExportButton();
                
                const clipboardText = await readClipboardData();
                
                if (!clipboardText) {
                    const errorMessage = autoExportSuccess ? 
                        (isZH ? 
                            '已尝试自动导出,但无法读取剪贴板数据\n\n请确保:\n1. 允许浏览器访问剪贴板\n2. 等待导出完成后重试' :
                            'Auto export attempted, but cannot read clipboard data\n\nPlease ensure:\n1. Allow browser to access clipboard\n2. Wait for export to complete and retry'
                        ) : 
                        (isZH ? 
                            '无法读取剪贴板数据\n\n请确保:\n1. 先点击"导出人物到剪贴板"按钮\n2. 允许浏览器访问剪贴板\n3. 剪贴板中有有效的角色数据' : 
                            'Cannot read clipboard data\n\nPlease ensure:\n1. Click "Export to clipboard" button first\n2. Allow browser to access clipboard\n3. Valid character data in clipboard'
                        );
                    alert(errorMessage);
                    return;
                }
                
                try {
                    characterData = JSON.parse(clipboardText);
                } catch (error) {
                    alert(isZH ? 
                        '剪贴板中的数据不是有效的JSON格式\n\n请确保先点击"导出人物到剪贴板"按钮' : 
                        'Data in clipboard is not valid JSON\n\nPlease ensure you clicked "Export to clipboard" button first');
                    return;
                }
                
                if (!isValidCharacterData(characterData)) {
                    alert(isZH ? 
                        '剪贴板中的数据不包含有效的角色信息\n\n请确保使用MWI Tools的"导出人物到剪贴板"功能' : 
                        'Data in clipboard does not contain valid character information\n\nPlease ensure you use MWI Tools "Export to clipboard" feature');
                    return;
                }
                
                // 重置调试信息
                state.debugInfo.firstSvgPath = null;
                state.debugInfo.iconCount = 0;
                
                const characterName = characterData.player?.name || characterData.character?.name || (isZH ? '角色' : 'Character');
                
                // 查找页面中的角色信息元素 - 获取最后一个(用于查看其他角色)
                let characterNameElement = null;
                const characterNameDivs = document.querySelectorAll('.CharacterName_characterName__2FqyZ');
                if (characterNameDivs.length > 0) {
                    // 取最后一个元素(用于查看其他角色)
                    const lastCharacterNameDiv = characterNameDivs[characterNameDivs.length - 1];
                    characterNameElement = lastCharacterNameDiv.outerHTML;
                }
                
                const modal = document.createElement('div');
                modal.className = 'character-card-modal';
                modal.innerHTML = `
                    <div class="modal-content">
                        <button class="close-modal">&times;</button>
                        <div class="instruction-banner">
                            ${isZH ? 
                                `MWI角色名片插件 v${VERSION} (数据来源: ${dataSource})` :
                                `MWI Character Card Plugin v${VERSION} (Data Source: ${dataSource})`
                            }
                        </div>
                        <div class="download-section">
                            <button class="download-card-btn">${isZH ? '下载名片' : 'Download Card'}</button>
                        </div>
                        ${generateCharacterCard(characterData, characterName, characterNameElement, false)}
                    </div>
                `;

                modal.querySelector('.close-modal').onclick = () => document.body.removeChild(modal);
                modal.querySelector('.download-card-btn').onclick = downloadCharacterCard;
                modal.onclick = (e) => { if (e.target === modal) document.body.removeChild(modal); };
                
                // 添加技能槽点击事件监听器(仅场景2需要)
                const skillSlots = modal.querySelectorAll('.skill-slot, .empty-skill-slot');
                skillSlots.forEach(slot => {
                    slot.addEventListener('click', function() {
                        const skillIndex = parseInt(this.getAttribute('data-skill-index'));
                        showSkillSelector(skillIndex);
                    });
                });
                
                document.body.appendChild(modal);
                
            } catch (error) {
                console.error('生成角色名片失败:', error);
                alert(isZH ? 
                    '生成角色名片时发生错误\n\n错误信息: ' + error.message : 
                    'Error occurred while generating character card\n\nError: ' + error.message);
            }
        }

        // 使用WebSocket数据生成名片(用于查看当前角色)
        async function showMyCharacterCard() {
            try {
                // 获取当前角色名
                const currentCharacterName = window.characterCardWebSocketData?.characterName || 
                    window.characterCardWebSocketData?.name || 
                    (isZH ? '角色' : 'Character');
                
                // 检查是否需要重置技能配置(角色切换)
                const configKey = `mwi_skill_config_${currentCharacterName}`;
                const savedConfig = localStorage.getItem(configKey);
                
                if (savedConfig) {
                    // 有保存的配置,检查是否匹配当前角色
                    try {
                        const configData = JSON.parse(savedConfig);
                        if (configData.characterName === currentCharacterName) {
                            // 角色匹配,保持现有配置
                            console.log(`使用保存的技能配置: ${currentCharacterName}`);
                        } else {
                            // 角色不匹配,重置配置
                            state.customSkills.selectedSkills = [];
                            console.log(`角色切换,重置技能配置: ${currentCharacterName}`);
                        }
                    } catch (error) {
                        // 配置数据错误,重置
                        state.customSkills.selectedSkills = [];
                        console.log('配置数据错误,重置技能配置');
                    }
                } else {
                    // 没有保存的配置,重置
                    state.customSkills.selectedSkills = [];
                }
                
                let characterData = null;
                let dataSource = isZH ? `WS数据` : `WebSocket Data`;
                
                // 检查是否有WebSocket数据
                if (!window.characterCardWebSocketData) {
                    alert(isZH ? 
                        '未找到当前角色数据\n\n请确保:\n1. 已登录游戏\n2. 等待游戏数据加载完成\n3. 刷新页面后重试' : 
                        'No current character data found\n\nPlease ensure:\n1. You are logged into the game\n2. Wait for game data to load\n3. Refresh the page and try again');
                    return;
                }
                
                const parsedData = window.characterCardWebSocketData;
                
                if (parsedData && parsedData.type === "init_character_data") {
                    // 将WebSocket数据格式转换为角色名片插件需要的格式
                    characterData = {
                        player: {
                            name: parsedData.characterName || parsedData.name || (isZH ? '角色' : 'Character'),
                            equipment: parsedData.characterItems || [],
                            characterItems: parsedData.characterItems || [],
                            staminaLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/stamina'))?.level || 0,
                            intelligenceLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/intelligence'))?.level || 0,
                            attackLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/attack'))?.level || 0,
                            powerLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/power'))?.level || 0,
                            defenseLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/defense'))?.level || 0,
                            rangedLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/ranged'))?.level || 0,
                            magicLevel: parsedData.characterSkills?.find(s => s.skillHrid.includes('/skills/magic'))?.level || 0
                        },
                        abilities: parsedData.characterAbilities || [],
                        characterSkills: parsedData.characterSkills || [],
                        houseRooms: parsedData.characterHouseRoomMap || {},
                        characterHouseRoomMap: parsedData.characterHouseRoomMap || {}
                    };
                } else {
                    alert(isZH ? 
                        'WebSocket数据格式不正确\n\n请刷新页面后重试' : 
                        'WebSocket data format is incorrect\n\nPlease refresh the page and try again');
                    return;
                }
                
                if (!isValidCharacterData(characterData)) {
                    alert(isZH ? 
                        'WebSocket数据不包含有效的角色信息\n\n请刷新页面后重试' : 
                        'WebSocket data does not contain valid character information\n\nPlease refresh the page and try again');
                    return;
                }
                
                // 重置调试信息
                state.debugInfo.firstSvgPath = null;
                state.debugInfo.iconCount = 0;
                
                const characterName = characterData.player?.name || characterData.character?.name || (isZH ? '角色' : 'Character');
                
                // 查找页面中的角色信息元素 - 获取第一个(右上角的当前用户)
                let characterNameElement = null;
                const characterNameDivs = document.querySelectorAll('.CharacterName_characterName__2FqyZ');
                if (characterNameDivs.length > 0) {
                    // 取第一个元素(右上角的当前用户)
                    const firstCharacterNameDiv = characterNameDivs[0];
                    characterNameElement = firstCharacterNameDiv.outerHTML;
                }
                
                const modal = document.createElement('div');
                modal.className = 'character-card-modal';
                modal.innerHTML = `
                    <div class="modal-content">
                        <button class="close-modal">&times;</button>
                        <div class="instruction-banner">
                            ${isZH ? 
                                `MWI角色名片插件 v${VERSION} (数据来源: ${dataSource})` :
                                `MWI Character Card Plugin v${VERSION} (Data Source: ${dataSource})`
                            }
                        </div>
                        <div class="download-section">
                            <div class="button-row">
                                <button class="download-card-btn">${isZH ? '下载名片' : 'Download Card'}</button>
                                <button class="save-skill-config-btn">${isZH ? '保存技能配置' : 'Save Skill Config'}</button>
                                <button class="load-skill-config-btn">${isZH ? '读取技能配置' : 'Load Skill Config'}</button>
                            </div>
                            <div class="skill-hint">
                                <span>${isZH ? '💡 点击技能图标可更换/添加展示的技能' : '💡 Click skill icons to change/add displayed skills'}</span>
                            </div>
                        </div>
                        ${generateCharacterCard(characterData, characterName, characterNameElement, true)}
                    </div>
                `;

                modal.querySelector('.close-modal').onclick = () => document.body.removeChild(modal);
                modal.querySelector('.download-card-btn').onclick = downloadCharacterCard;
                modal.onclick = (e) => { if (e.target === modal) document.body.removeChild(modal); };
                
                // 添加技能配置按钮事件监听器
                modal.querySelector('.save-skill-config-btn').onclick = () => {
                    saveSkillConfig(characterName);
                };
                modal.querySelector('.load-skill-config-btn').onclick = () => {
                    loadSkillConfig(characterName);
                };
                
                // 添加技能槽点击事件监听器
                const skillSlots = modal.querySelectorAll('.skill-slot, .empty-skill-slot');
                skillSlots.forEach(slot => {
                    slot.addEventListener('click', function() {
                        const skillIndex = parseInt(this.getAttribute('data-skill-index'));
                        showSkillSelector(skillIndex);
                    });
                });
                
                document.body.appendChild(modal);
                
            } catch (error) {
                console.error('生成我的角色名片失败:', error);
                alert(isZH ? 
                    '生成我的角色名片时发生错误\n\n错误信息: ' + error.message : 
                    'Error occurred while generating my character card\n\nError: ' + error.message);
            }
        }

        function addCharacterCardButton() {
            const checkElem = () => {
                const selectedElement = document.querySelector(`div.SharableProfile_overviewTab__W4dCV`);
                if (selectedElement) {
                    clearInterval(state.timer);
                    if (selectedElement.querySelector('.character-card-btn')) return;

                    const button = document.createElement("button");
                    button.className = 'character-card-btn';
                    button.textContent = isZH ? "查看角色名片" : "View Character Card";
                    button.style.cssText = `
                        border-radius: 6px; height: 24px; background-color: #17a2b8; color: white;
                        box-shadow: 0 2px 4px rgba(0,0,0,0.1); border: 0px; margin: 10px auto; 
                        display: inline-block; padding: 0 16px; min-width: 140px; max-width: 180px;
                        font-size: 13px; cursor: pointer; transition: all 0.2s ease;
                    `;
                    
                    // 添加hover效果
                    button.addEventListener('mouseenter', () => {
                        button.style.backgroundColor = '#138496';
                        button.style.transform = 'translateY(-1px)';
                    });
                    
                    button.addEventListener('mouseleave', () => {
                        button.style.backgroundColor = '#17a2b8';
                        button.style.transform = 'translateY(0)';
                    });
                    
                    button.onclick = () => { 
                        showCharacterCard(); 
                        return false; 
                    };
                    
                    // 创建按钮容器并居中
                    const buttonContainer = document.createElement('div');
                    buttonContainer.style.cssText = 'text-align: center; margin-top: 10px;';
                    buttonContainer.appendChild(button);
                    
                    // 插入按钮容器
                    selectedElement.appendChild(buttonContainer);
                    
                    console.log('角色名片按钮已添加');
                    return false;
                }
            };
            state.timer = setInterval(checkElem, 1000);
        }

        // 在右上角角色信息区域添加"我的角色名片"按钮
        function addMyCharacterCardButton() {
            const checkMyButton = () => {
                const headerNameElements = document.querySelectorAll('.Header_name__227rJ');
                if (headerNameElements.length > 0) {
                    // 找到右上角的角色信息容器
                    const headerNameElement = headerNameElements[0];
                    
                    // 检查是否已经添加过按钮
                    if (headerNameElement.querySelector('.my-character-card-btn')) {
                        return;
                    }
                    
                    // 创建按钮
                    const myButton = document.createElement("button");
                    myButton.className = 'my-character-card-btn';
                    myButton.textContent = isZH ? "我的角色名片" : "My Character Card";
                    myButton.style.cssText = `
                        border-radius: 4px; height: 20px; background-color: #28a745; color: white;
                        box-shadow: 0 1px 3px rgba(0,0,0,0.2); border: 0px; margin-left: 8px;
                        display: inline-block; padding: 0 8px; font-size: 11px; cursor: pointer; 
                        transition: all 0.2s ease; vertical-align: middle;
                    `;
                    
                    // 添加hover效果
                    myButton.addEventListener('mouseenter', () => {
                        myButton.style.backgroundColor = '#218838';
                        myButton.style.transform = 'translateY(-1px)';
                    });
                    
                    myButton.addEventListener('mouseleave', () => {
                        myButton.style.backgroundColor = '#28a745';
                        myButton.style.transform = 'translateY(0)';
                    });
                    
                    myButton.onclick = () => { 
                        showMyCharacterCard(); 
                        return false; 
                    };
                    
                    // 将按钮插入到Header_name容器中
                    headerNameElement.appendChild(myButton);
                    
                    console.log('我的角色名片按钮已添加到右上角');
                    return false;
                }
            };
            
            // 使用定时器检查并添加按钮
            const myButtonTimer = setInterval(checkMyButton, 1000);
            
            // 清理定时器(当按钮添加成功后)
            setTimeout(() => {
                clearInterval(myButtonTimer);
            }, 10000); // 10秒后停止检查
        }

                 async function init() {
             console.log(`MWI角色名片插件 v${VERSION}`);
            console.log('使用说明:');
            console.log('1. 在角色信息界面点击"查看角色名片"按钮 - 使用剪贴板数据');
            console.log('2. 在右上角点击"我的角色名片"按钮 - 使用WebSocket数据');
            
            createModalStyles();
            const spritesLoaded = await state.svgTool.loadSpriteSheets();
            console.log(`图标系统初始化${spritesLoaded ? '成功' : '失败'},将使用${spritesLoaded ? 'MWI原版SVG图标' : '后备图标显示'}`);
            if (spritesLoaded) {
                console.log('SVG Sprite文件:', state.svgTool.spriteSheets);
            }
            
            // 设置WebSocket Hook
            hookWebSocket();
            
            // 监听角色数据可用事件
            window.addEventListener('characterDataAvailable', function(event) {
                // 静默处理事件
            });
            
            addCharacterCardButton();
            addMyCharacterCardButton();
            
            // 创建一个MutationObserver来监听body的子节点变化
            state.observer = new MutationObserver((mutationsList, observer) => {
                for(const mutation of mutationsList) {
                    if (mutation.type === 'childList') {
                        // 检查是否是SharableProfile_overviewTab__W4dCV的子节点变化
                        if (mutation.target.classList.contains('SharableProfile_overviewTab__W4dCV')) {
                            // 延迟执行,确保DOM更新完成
                            setTimeout(addCharacterCardButton, 100);
                        }
                    }
                }
            });
            state.observer.observe(document.body, { childList: true, subtree: true });
        }

        // 清理函数
        function cleanup() {
            if (state.observer) {
                state.observer.disconnect();
                state.observer = null;
            }
            if (state.timer) {
                clearInterval(state.timer);
                state.timer = null;
            }
        }

        // 暴露数据给其他脚本的函数
        function exposeDataToOtherScripts() {
            // 创建一个全局函数,让MWI Tools可以调用
            window.exposeMWIToolsData = function(data) {
                window.mwiToolsData = data;
            };
            
            // 监听来自MWI Tools的消息
            window.addEventListener('message', function(event) {
                if (event.source === window && event.data && event.data.type === 'MWI_TOOLS_DATA') {
                    window.mwiToolsData = event.data.data;
                }
            });
            
            // 监听localStorage变化
            window.addEventListener('storage', function(event) {
                if (event.key === 'init_character_data' && event.newValue) {
                    try {
                        const data = JSON.parse(event.newValue);
                        window.mwiToolsData = data;
                    } catch (error) {
                        // 静默处理错误
                    }
                }
            });
        }

        // WebSocket Hook函数 - 参考MWI Tools的实现
        function hookWebSocket() {
            // 检查是否已经hook过
            if (window.characterCardWebSocketHooked) {
                return;
            }
            
            try {
                // 获取MessageEvent.prototype.data的属性描述符
                const dataProperty = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
                if (!dataProperty) {
                    return;
                }
                
                const oriGet = dataProperty.get;
                
                // 重写getter
                dataProperty.get = function() {
                    const socket = this.currentTarget;
                    
                    // 检查是否是WebSocket连接
                    if (!(socket instanceof WebSocket)) {
                        return oriGet.call(this);
                    }
                    
                    // 检查是否是MWI的WebSocket连接
                    if (socket.url.indexOf("api.milkywayidle.com/ws") <= -1 && 
                        socket.url.indexOf("api-test.milkywayidle.com/ws") <= -1) {
                        return oriGet.call(this);
                    }
                    
                    // 获取原始消息
                    const message = oriGet.call(this);
                    
                    // 防止循环调用
                    Object.defineProperty(this, "data", { value: message });
                    
                    // 处理消息
                    handleWebSocketMessage(message);
                    
                    return message;
                };
                
                // 重新定义属性
                Object.defineProperty(MessageEvent.prototype, "data", dataProperty);
                
                // 标记已hook
                window.characterCardWebSocketHooked = true;
                
            } catch (error) {
                // 静默处理错误
            }
        }
        
        // 处理WebSocket消息
        function handleWebSocketMessage(message) {
            try {
                const obj = JSON.parse(message);
                
                // 处理角色数据
                if (obj && obj.type === "init_character_data") {
                    console.log('=== 检测到角色数据 ===');
                    console.log('角色名称:', obj.characterName);
                    console.log('装备数量:', obj.characterItems?.length || 0);
                    console.log('技能数量:', obj.characterSkills?.length || 0);
                    console.log('能力数量:', obj.characterAbilities?.length || 0);
                    console.log('房屋数据:', obj.characterHouseRoomMap);
                    console.log('完整数据:', obj);
                    
                    // 存储到全局变量
                    window.mwiToolsData = obj;
                    window.characterCardWebSocketData = obj;
                    
                    // 存储到localStorage
                    try {
                        localStorage.setItem('init_character_data', message);
                        console.log('已存储到localStorage');
                    } catch (error) {
                        console.log('localStorage存储失败:', error);
                    }
                    
                    // 触发数据可用事件
                    window.dispatchEvent(new CustomEvent('characterDataAvailable', {
                        detail: obj
                    }));
                    
                    console.log('=== 角色数据处理完成 ===');
                }
                
            } catch (error) {
                // 静默处理解析错误,不打印日志
            }
        }

        // 在脚本卸载时清理
        window.addEventListener('unload', cleanup);

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', init);
        } else {
            init();
        }
        
        // 初始化数据暴露机制
        exposeDataToOtherScripts();
        
        // 保存技能配置函数
        function saveSkillConfig(characterName) {
            try {
                const configKey = `mwi_skill_config_${characterName}`;
                
                // 只保存技能ID和位置,不保存等级
                const simplifiedSkills = state.customSkills.selectedSkills.map((skill, index) => ({
                    abilityHrid: skill.abilityHrid,
                    position: index
                }));
                
                const configData = {
                    characterName: characterName,
                    selectedSkills: simplifiedSkills,
                    timestamp: Date.now()
                };
                
                localStorage.setItem(configKey, JSON.stringify(configData));
                
                // 显示成功提示
                const saveBtn = document.querySelector('.save-skill-config-btn');
                const originalText = saveBtn.textContent;
                saveBtn.textContent = isZH ? '保存成功!' : 'Saved!';
                saveBtn.style.backgroundColor = '#28a745';
                
                setTimeout(() => {
                    saveBtn.textContent = originalText;
                    saveBtn.style.backgroundColor = '#17a2b8';
                }, 2000);
                
                console.log(`技能配置已保存: ${characterName}`);
            } catch (error) {
                console.error('保存技能配置失败:', error);
                alert(isZH ? '保存技能配置失败' : 'Failed to save skill config');
            }
        }
        
        // 读取技能配置函数
        function loadSkillConfig(characterName) {
            try {
                const configKey = `mwi_skill_config_${characterName}`;
                const savedConfig = localStorage.getItem(configKey);
                
                if (!savedConfig) {
                    alert(isZH ? 
                        `未找到角色 "${characterName}" 的技能配置\n\n请先保存技能配置` : 
                        `No skill config found for character "${characterName}"\n\nPlease save skill config first`);
                    return false;
                }
                
                const configData = JSON.parse(savedConfig);
                
                // 验证配置数据
                if (!configData.selectedSkills || !Array.isArray(configData.selectedSkills)) {
                    alert(isZH ? '技能配置数据格式错误' : 'Invalid skill config data format');
                    return false;
                }
                
                // 从WebSocket数据获取最新技能信息并应用配置
                const allSkills = window.characterCardWebSocketData?.characterAbilities || [];
                const restoredSkills = [];
                
                configData.selectedSkills.forEach(savedSkill => {
                    if (savedSkill.abilityHrid) {
                        // 从WebSocket数据中找到对应的技能
                        const currentSkill = allSkills.find(skill => 
                            skill.abilityHrid === savedSkill.abilityHrid
                        );
                        
                        if (currentSkill) {
                            // 使用最新的等级信息
                            restoredSkills[savedSkill.position] = {
                                abilityHrid: currentSkill.abilityHrid,
                                level: currentSkill.level,
                                slotNumber: currentSkill.slotNumber
                            };
                        }
                    }
                });
                
                // 应用恢复的技能配置
                state.customSkills.selectedSkills = restoredSkills;
                
                // 重新生成技能面板
                const characterCard = document.querySelector('#character-card');
                if (characterCard) {
                    const skillPanel = characterCard.querySelector('.skill-panel');
                    if (skillPanel) {
                        const characterData = {
                            abilities: window.characterCardWebSocketData?.characterAbilities || [],
                            characterSkills: window.characterCardWebSocketData?.characterSkills || []
                        };
                        const newSkillPanel = generateSkillPanel(characterData, true);
                        skillPanel.innerHTML = newSkillPanel.replace(/<div class="skill-panel">([\s\S]*?)<\/div>$/, '$1');
                        
                        // 重新添加事件监听器
                        const skillSlots = skillPanel.querySelectorAll('.skill-slot, .empty-skill-slot');
                        skillSlots.forEach(slot => {
                            slot.addEventListener('click', function() {
                                const skillIndex = parseInt(this.getAttribute('data-skill-index'));
                                showSkillSelector(skillIndex);
                            });
                        });
                    }
                }
                
                // 显示成功提示
                const loadBtn = document.querySelector('.load-skill-config-btn');
                const originalText = loadBtn.textContent;
                loadBtn.textContent = isZH ? '读取成功!' : 'Loaded!';
                loadBtn.style.backgroundColor = '#28a745';
                
                setTimeout(() => {
                    loadBtn.textContent = originalText;
                    loadBtn.style.backgroundColor = '#17a2b8';
                }, 2000);
                
                console.log(`技能配置已读取: ${characterName}`);
                return true;
            } catch (error) {
                console.error('读取技能配置失败:', error);
                alert(isZH ? '读取技能配置失败' : 'Failed to load skill config');
                return false;
            }
        }
        
        // 将函数暴露到全局作用域
        if (typeof window !== 'undefined') {
            window.showSkillSelector = showSkillSelector;
            window.selectSkill = selectSkill;
        }

    })(); // 结束立即执行函数

})();