GX游戏库
返回上一页
魔法大师[Master of Magic] 游戏封面

魔法大师[Master of Magic]

2026/6/7 05:37:36 PC
策略战棋动作冒险
平台PC
分类策略战棋 / 动作冒险
更新时间2026/6/7
浏览量0

游戏介绍

Version: 1.09.17.3 (90039)

Master of Magic (2022) является римейком некогда классического проекта, который в свое время привлек внимание большого количества людей. Пользователям, как и прежде, предстоит пойти продолжительный путь по территории сразу двух соседних миров - Аркануса и Миррора, чтобы столкнуться с сильнейшими чародеями за звание сильнейшего. Всего на выбор предлагается 14 разных волшебников со своими уникальными способностями, которые, в том числе являются представителями разных школ. Поэтому, кого бы не выбрал геймер, это в любом случае будет уникальный опыт.

Важно учитывать, что хоть в Master of Magic (2022) и предлагается сыграть за конкретного персонажа, сражаться предстоит не его руками. Этот маг исполняет роль командира и полководца, собирая и обучая целые группы эльфов, драконов, миньонов и прочих юнитов. Именно в них содержится вся убойная сила, но персонаж способен оказывать поддержку, используя заклинания и разрушая строй врага. Каждый бой происходит в пошаговом режиме на отдельных отрезках карты. Каждый сектор разделен на шестиугольники, за счет чего сразу можно понять, как двигается отряд. Более того, усиливать свой отряд можно не только новыми бойцами, но и при помощи случайно генерирующихся предметов. Всего их может быть более 250, и каждая такая штука дает свои преимущества на полях сражений. Поэтому, совершенно не обязательно подстраиваться под единственную стратегию, а постоянно менять подход к прохождению, удивляя оппонентов своими действиями.

System Requirements:
ОС: Windows 8 / 10 (64 bit)
Процессор: Intel Core i5-4460
Оперативная память: 8 ГБ
Видеокарта: Direct X11
Место на диске: 7 ГБ

游戏图片

魔法大师[Master of Magic] 游戏截图1魔法大师[Master of Magic] 游戏截图2魔法大师[Master of Magic] 游戏截图3魔法大师[Master of Magic] 游戏截图4魔法大师[Master of Magic] 游戏截图5魔法大师[Master of Magic] 游戏截图6魔法大师[Master of Magic] 游戏截图7魔法大师[Master of Magic] 游戏截图8魔法大师[Master of Magic] 游戏截图9魔法大师[Master of Magic] 游戏截图10

下载链接

相关推荐

× 放大图片
前,DOM 已就绪,直接执行) ---- YXZYFX.setupLazyLoading(); YXZYFX.setupMobileMenu('menu-toggle', 'menu-dropdown'); // 详情页固定画布缩放:按当前可用宽度等比例缩小,PC/移动端保持同一布局。 function setupDetailFixedScale() { var box = document.getElementById('detail-scale-box'); var canvas = document.getElementById('detail-fixed-canvas'); if (!box || !canvas) return; var DESIGN_WIDTH = 1180; var timer = null; function availableWidth() { var vw = window.visualViewport && window.visualViewport.width ? window.visualViewport.width : 0; var iw = window.innerWidth || 0; var cw = document.documentElement.clientWidth || 0; return Math.max(320, Math.floor(vw || iw || cw || DESIGN_WIDTH)); } function update() { var isMobile = (window.innerWidth || 0) <= 768; document.documentElement.classList.toggle('mobile-layout', isMobile); document.documentElement.classList.toggle('desktop-layout', !isMobile); if (document.body) { document.body.classList.toggle('mobile-layout', isMobile); document.body.classList.toggle('desktop-layout', !isMobile); } if (isMobile) { canvas.style.width = ''; canvas.style.minWidth = ''; canvas.style.maxWidth = ''; canvas.style.transform = 'none'; canvas.style.transformOrigin = ''; box.style.width = ''; box.style.height = ''; return; } var available = Math.max(320, availableWidth() - 16); var scale = Math.min(1, available / DESIGN_WIDTH); var visualWidth = Math.ceil(DESIGN_WIDTH * scale); canvas.style.width = DESIGN_WIDTH + 'px'; canvas.style.minWidth = DESIGN_WIDTH + 'px'; canvas.style.maxWidth = 'none'; canvas.style.transform = 'scale(' + scale + ')'; canvas.style.transformOrigin = '0 0'; box.style.width = visualWidth + 'px'; box.style.height = Math.ceil(canvas.scrollHeight * scale) + 'px'; } function schedule(delay) { clearTimeout(timer); timer = setTimeout(update, typeof delay === 'number' ? delay : 50); } window.__yxDetailScaleUpdate = update; window.addEventListener('resize', function(){ schedule(50); }, { passive: true }); window.addEventListener('orientationchange', function(){ schedule(180); }, { passive: true }); if (window.visualViewport) window.visualViewport.addEventListener('resize', function(){ schedule(50); }, { passive: true }); if (document.fonts && document.fonts.ready) { try { document.fonts.ready.then(function(){ schedule(0); }); } catch(_) {} } if (window.ResizeObserver) { try { new ResizeObserver(function(){ schedule(80); }).observe(canvas); } catch(_) {} } document.addEventListener('load', function(e){ if (e && e.target && canvas.contains(e.target)) schedule(80); }, true); update(); window.addEventListener('load', function(){ update(); setTimeout(update, 300); }, { once: true }); } setupDetailFixedScale(); (function(){ function updateLayoutClass(){ var mobile = (window.innerWidth || 0) <= 768; document.documentElement.classList.toggle('mobile-layout', mobile); document.documentElement.classList.toggle('desktop-layout', !mobile); if (document.body) { document.body.classList.toggle('mobile-layout', mobile); document.body.classList.toggle('desktop-layout', !mobile); } if (window.__yxDetailScaleUpdate) window.__yxDetailScaleUpdate(); } window.addEventListener('resize', function(){ setTimeout(updateLayoutClass, 100); }, { passive: true }); window.addEventListener('orientationchange', function(){ setTimeout(updateLayoutClass, 200); }, { passive: true }); })(); function normalizeJsDelivrUrl(url) { if (typeof url !== 'string') return url; return url.replace(/(?:cdn|fastly)\.jsdelivr\.net|jsd\.cdn\.zzko\.cn|jsd\.onmicrosoft\.cn/g, 'gcore.jsdelivr.net'); } function toArray(value) { if (Array.isArray(value)) return value.filter(function(v) { return v !== null && v !== undefined && String(v).trim() !== ''; }); if (typeof value === 'string') { return value.split(/[,,|、\/]/).map(function(v) { return v.trim(); }).filter(Boolean); } return []; } function pickText(obj, keys, fallback) { for (var i = 0; i < keys.length; i++) { var value = obj && obj[keys[i]]; if (value !== null && value !== undefined && String(value).trim() !== '') return String(value); } return fallback || ''; } function getGameTitle(game) { return pickText(game, ['title', 'name', 'gameName', 'gameTitle'], '游戏详情'); } function getGameContent(game) { return pickText(game, ['content', 'description', 'desc', 'intro', 'introduction', 'gameIntro', 'detail', 'details', 'body'], '暂无游戏介绍'); } function renderTextWithBreaks(text) { return YXZYFX.escapeHtml(String(text || '')).replace(/\n/g, '
'); } function isScrapeCommandLine(line) { var value = String(line || '').trim(); return /^(?:sc\s+(?:create|start|stop|delete|query|qc)\b|bcdedit\b|reg\s+|net\s+|cmd\b|powershell\b|wmic\b|schtasks\b|dism\b|sfc\b|chkdsk\b)/i.test(value) || /^["']?[a-z]:\\/i.test(value) || /^\.\\/.test(value); } function renderScrapeSectionContent(text) { var raw = String(text || '').replace(/\r\n?/g, '\n').trim(); if (!raw) return ''; return raw.split(/\n{2,}/).map(function(paragraph) { var lines = paragraph.split('\n').map(function(line) { var value = String(line || '').trim(); if (!value) return ''; var escaped = YXZYFX.escapeHtml(value); if (isScrapeCommandLine(value)) return '' + escaped + ''; return escaped; }).filter(Boolean); return lines.length ? '

' + lines.join('
') + '

' : ''; }).filter(Boolean).join(''); } function normalizeSectionTitleForCheck(text) { return String(text || '').replace(/[\s\u00a0]+/g, ' ').replace(/[::]+$/g, '').trim().toLowerCase(); } function isAllowedScrapeSectionTitle(key, title) { var value = normalizeSectionTitleForCheck(title); if (!value) return true; if (key === 'install') return value.indexOf('安装和启动') !== -1 || /установка\s+и\s+запуск/i.test(value); if (key === 'addons') return value.indexOf('补充内容列表') !== -1 || value.indexOf('补充内容') !== -1 || /список\s+дополнений/i.test(value); if (key === 'notice') return value.indexOf('提示') !== -1 || /примечание/i.test(value); return false; } function normalizeScrapeSections(game) { var raw = (game && (game.scrapeSections || game.extraSections || game.byrutSections)) || {}; var result = []; [ ['install', '安装和启动'], ['addons', '补充内容列表'], ['notice', '提示'] ].forEach(function(pair) { var key = pair[0]; var fallbackTitle = pair[1]; var section = raw && raw[key]; if (!section) return; if (typeof section === 'string') section = { content: section }; if (!isAllowedScrapeSectionTitle(key, section.title || '')) return; var content = String(section.content || '').trim(); if (!content) return; result.push({ key: key, title: fallbackTitle, content: content }); }); return result; } function renderScrapeSections(game) { var box = document.getElementById('detail-extra-sections'); if (!box) return; var sections = normalizeScrapeSections(game); if (!sections.length) { box.innerHTML = ''; return; } box.innerHTML = sections.map(function(section) { var title = YXZYFX.escapeHtml(section.title); var body = renderScrapeSectionContent(section.content); if (section.key === 'notice') { return '
⚠️ ' + title + '
' + body + '
'; } return '
' + title + '
' + body + '
'; }).join(''); } function normalizeSourceUpdatedText(text) { var value = String(text || '') .replace(/\s+/g, ' ') .replace(/^Публикация\s+обновлена\s*[-—:]\s*/i, '') .replace(/^Обновлено\s*[-—:]\s*/i, '') .trim(); var months = { 'января': 1, 'февраля': 2, 'марта': 3, 'апреля': 4, 'мая': 5, 'июня': 6, 'июля': 7, 'августа': 8, 'сентября': 9, 'октября': 10, 'ноября': 11, 'декабря': 12 }; var match = value.match(/(\d{1,2})\s+([а-яё]+)\s+(\d{4})/i); if (match && months[match[2].toLowerCase()]) { return match[3] + '年' + months[match[2].toLowerCase()] + '月' + parseInt(match[1], 10) + '日'; } return value; } function renderSourceUpdatedText(game) { var box = document.getElementById('detail-source-update'); if (!box) return; var value = normalizeSourceUpdatedText(game && (game.sourceUpdatedText || game.sourceUpdateText || game.sourceUpdated || '')); if (!value) { box.hidden = true; box.innerHTML = ''; return; } box.hidden = false; box.innerHTML = '更新时间:' + YXZYFX.escapeHtml(value) + ''; } function getGameImages(game) { var images = []; ['images', 'screenshots', 'gameImages', 'imageList'].forEach(function(key) { images = images.concat(toArray(game && game[key])); }); ['coverImage', 'cover', 'coverUrl', 'image', 'poster', 'thumb', 'thumbnail'].forEach(function(key) { var value = game && game[key]; if (value && images.indexOf(value) === -1) images.unshift(value); }); return images.map(normalizeJsDelivrUrl).filter(Boolean).filter(function(v, i, arr) { return arr.indexOf(v) === i; }); } function renderRelatedGames(games) { var box = document.getElementById('related-games'); if (!box) return; if (!games || !games.length) { box.innerHTML = '

暂无相关推荐

'; return; } box.innerHTML = games.map(function(g) { var title = YXZYFX.escapeHtml(getGameTitle(g)); var imgs = getGameImages(g); var cover = imgs[0] || 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 300 400%27%3E%3Crect width=%27300%27 height=%27400%27 fill=%27%23111827%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 fill=%27%239ca3af%27 text-anchor=%27middle%27 dominant-baseline=%27middle%27%3E暂无封面%3C/text%3E%3C/svg%3E'; return '' + title + '
' + title + '
'; }).join(''); } function loadRelatedGames(id) { var box = document.getElementById('related-games'); if (!box || !id) return; fetch('/api/games/related/' + encodeURIComponent(id) + '?limit=8') .then(function(response) { return response.ok ? response.json() : { games: [] }; }) .then(function(data) { renderRelatedGames((data && data.games) || []); }) .catch(function() { if (box) box.innerHTML = '

暂无相关推荐

'; }); } var currentGame = null; function renderGameDetail(game) { currentGame = game || {}; var title = getGameTitle(game); var content = getGameContent(game); var images = getGameImages(game); var categories = toArray(game.category); var tags = toArray(game.tags); var dateValue = game.createdAt || Date.now(); document.title = title + ' - GX游戏库'; // SSR 已注入精确的 meta description,客户端仅在 SSR 未生效时更新 var metaDesc = document.querySelector('meta[name="description"]'); if (metaDesc && metaDesc.getAttribute('content') === 'GX游戏库 - PC游戏资源详情页,免费下载,解压即玩') { metaDesc.setAttribute('content', title + ' - GX游戏库,' + content.substring(0, 120)); } document.getElementById('detail-title').textContent = title; document.getElementById('detail-content').innerHTML = renderTextWithBreaks(content); renderScrapeSections(game); renderSourceUpdatedText(game); document.getElementById('detail-date').textContent = '发布时间:' + new Date(dateValue).toLocaleString(); var pm = String(title || '').match(/^\[([^\]]+)\]/i); document.getElementById('detail-platform').textContent = '平台:' + (pm ? pm[1].toUpperCase() : 'PC'); var catWrapper = document.getElementById('detail-category-wrapper'); var catList = document.getElementById('detail-category-list'); if (categories.length > 0) { catList.innerHTML = categories.map(function(c) { return '' + YXZYFX.escapeHtml(c) + ''; }).join(''); catWrapper.style.display = 'block'; } else { catWrapper.style.display = 'none'; } var tc = document.getElementById('detail-tags'); tc.innerHTML = tags.length ? tags.slice(0, 24).map(function(t) { return '' + YXZYFX.escapeHtml(t) + ''; }).join('') : ''; var coverEl = document.getElementById('detail-cover'); if (coverEl) coverEl.src = images[0] || 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 300 400%27%3E%3Crect width=%27300%27 height=%27400%27 fill=%27%23111827%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 fill=%27%239ca3af%27 text-anchor=%27middle%27 dominant-baseline=%27middle%27%3E暂无封面%3C/text%3E%3C/svg%3E'; var ig = document.getElementById('detail-images'); ig.innerHTML = ''; if (images.length > 0) { images.forEach(function(url, i) { var img = document.createElement('img'); if (i === 0) { img.src = url; } else { img.loading = 'lazy'; img.dataset.src = url; img.src = 'data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 200 150%27%3E%3Crect fill=%27%231a1a1a%27 width=%27200%27 height=%27150%27/%3E%3C/svg%3E'; } img.className = 'grid-image'; img.alt = title; ig.appendChild(img); YXZYFX.observeImage(img); }); } else { ig.innerHTML = '

暂无游戏图片

'; } var ds = document.getElementById('detail-downloads'); ds.innerHTML = ''; var svcs = [ { k: 'kuake', n: '夸克网盘', i: 'fas fa-cloud-download-alt' }, { k: 'xunlei', n: '迅雷网盘', i: 'fas fa-bolt' } ]; var hasDownload = false; svcs.forEach(function(svc) { var dl = (game && game.downloads && game.downloads[svc.k]) || null; if (dl && dl.visible !== false) { hasDownload = true; var di = document.createElement('div'); di.className = 'download-item'; var safePassword = dl.password ? YXZYFX.escapeHtml(dl.password) : ''; di.innerHTML = '
' + svc.n + '
' + (safePassword ? '
密码: ' + safePassword + '
' : '') + '
'; var btn = di.querySelector('.download-btn'); btn.dataset.disk = svc.k; if (dl.password) btn.dataset.password = dl.password; ds.appendChild(di); } }); if (!hasDownload) ds.innerHTML = '

暂无下载链接

'; var summary = document.getElementById('resource-summary'); if (summary) { var updated = new Date(dateValue).toLocaleDateString(); summary.innerHTML = '
平台PC
' + '
分类' + YXZYFX.escapeHtml((categories.length ? categories : ['其他游戏']).slice(0, 2).join(' / ')) + '
' + '
更新时间' + YXZYFX.escapeHtml(updated) + '
' + '
浏览量' + YXZYFX.escapeHtml(String(game.views || 0)) + '
'; } loadRelatedGames(game._id); // 仅在 SSR 未注入完整 JSON-LD 时才由客户端补充(SSR 版本更完整,含 url/publisher/dateModified) try { var existingSeoJsonLd = document.querySelector('script[data-seo-jsonld]'); if (!existingSeoJsonLd) { var jsonLd = { '@context': 'https://schema.org', '@type': 'VideoGame', 'name': title, 'description': content.substring(0, 200), 'url': window.location.href.split('?')[0], 'genre': tags.join(', '), 'gamePlatform': 'PC', 'dateModified': new Date(dateValue).toISOString(), 'publisher': { '@type': 'Organization', 'name': 'GX游戏库' } }; if (images.length > 0) jsonLd.image = images[0]; var scriptTag = document.createElement('script'); scriptTag.type = 'application/ld+json'; scriptTag.setAttribute('data-seo-jsonld', ''); scriptTag.textContent = JSON.stringify(jsonLd); document.head.appendChild(scriptTag); } } catch (e) {} } function getCurrentGameId() { var urlParams = new URLSearchParams(window.location.search); var resolvedId = window.__SEO_GAME_ID__ || urlParams.get('id'); if (!resolvedId) { var pathMatch = window.location.pathname.match(/\/game\/([a-f0-9]{24})\.html$/i); if (pathMatch) resolvedId = pathMatch[1]; } if (!resolvedId && currentGame && currentGame._id) resolvedId = currentGame._id; return resolvedId || ''; } var gameId = getCurrentGameId(); if (gameId && window.__INITIAL_GAME__ && String(window.__INITIAL_GAME__._id || '') === String(gameId)) { try { renderGameDetail(window.__INITIAL_GAME__); } catch (e) {} } if (gameId) { fetch('/api/games/' + gameId) .then(function(response) { if (!response.ok) throw new Error('游戏不存在'); return response.json(); }) .then(function(game) { renderGameDetail(game || {}); }) .catch(function(error) { console.error('加载游戏详情失败:', error); var titleEl = document.getElementById('detail-title'); var contentEl = document.getElementById('detail-content'); var downloadsEl = document.getElementById('detail-downloads'); if (titleEl) titleEl.textContent = '游戏详情加载失败'; if (contentEl) contentEl.innerHTML = '

当前资源详情加载失败,但页面不会再自动跳回首页。请刷新页面,或返回首页重新进入。

'; if (downloadsEl) downloadsEl.innerHTML = '

暂无下载链接

'; }); } else { window.location.href = 'index.html'; } function isPC() { const userAgentInfo = navigator.userAgent; const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']; let flag = true; for (let v = 0; v < Agents.length; v++) { if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; } } return flag; } const downloadModal = document.getElementById('download-modal'); const modalClose = document.getElementById('modal-close'); const qrcode = document.getElementById('qrcode'); modalClose.addEventListener('click', function() { downloadModal.classList.remove('active'); }); downloadModal.addEventListener('click', function(e) { if (e.target === downloadModal) { downloadModal.classList.remove('active'); } }); async function loadModalSettings() { try { const response = await fetch('/api/public/settings?t=' + Date.now()); const setting = await response.json(); if (response.ok && setting.downloadModal) { updateModalContent(setting.downloadModal); YXZYFX.safeSetItem('yxzyfx_downloadModal', JSON.stringify(setting.downloadModal)); YXZYFX.safeSetItem('yxzyfx_downloadModal_time', Date.now().toString()); } else { loadModalSettingsFromLocalStorage(); } } catch (error) { loadModalSettingsFromLocalStorage(); } } function loadModalSettingsFromLocalStorage() { const savedSettings = YXZYFX.safeGetItem('yxzyfx_downloadModal'); const savedTime = YXZYFX.safeGetItem('yxzyfx_downloadModal_time'); if (savedSettings) { try { const settings = JSON.parse(savedSettings); updateModalContent(settings); } catch (e) {} } } function updateModalContent(settings) { const modalTitle = downloadModal.querySelector('h3'); if (modalTitle) { modalTitle.textContent = settings.title || '下载地址获取成功'; } const modalSubtitle = downloadModal.querySelector('p'); if (modalSubtitle) { modalSubtitle.textContent = settings.subtitle || '推荐使用手机扫码转存,移动端保存成功率更高,防和谐下载更稳定'; } const instructions = downloadModal.querySelector('.modal-instructions'); if (instructions) { if (settings.introduction) { const lines = settings.introduction.split('\n'); let instructionsHTML = ''; lines.forEach(line => { line = line.trim(); if (line) { var safeLine = YXZYFX.escapeHtml(line); if (line.match(/^[一二三四五六七八九十]+、|^\d+\.|^[\d]+、/)) { instructionsHTML += '

' + safeLine + '

'; } else { instructionsHTML += '

' + safeLine + '

'; } } }); instructions.innerHTML = instructionsHTML; } else { instructions.innerHTML = `

一、如何获取解压密码?

请点击下方【复制解压码】按钮,将密码粘贴到解压框中以解压文件。

二、如何下载?

手机保存资源,PC端网盘进行下载,复制解压码进行解压

三、注意事项:

游戏运行库是最基础环境,若游戏报错,点击下载

解压路径不能包含中文

更多问题请查看【常见问题】模块

`; } } } function openReportModal() { var existing = document.getElementById('report-modal'); if (existing) existing.remove(); var title = getGameTitle(currentGame || {}) || document.getElementById('detail-title')?.textContent || '当前资源'; var modalHtml = ` `; document.body.insertAdjacentHTML('beforeend', modalHtml); document.body.classList.add('gx-modal-open'); document.body.style.overflow = 'hidden'; var modal = document.getElementById('report-modal'); var closeBtn = document.getElementById('report-modal-close'); var cancelBtn = document.getElementById('report-modal-cancel'); if (closeBtn) closeBtn.addEventListener('click', closeReportModal); if (cancelBtn) cancelBtn.addEventListener('click', closeReportModal); if (modal) { modal.addEventListener('click', function(evt) { if (evt.target === modal) closeReportModal(); }); } var detailInput = document.getElementById('report-detail'); var count = document.getElementById('report-char-count'); if (detailInput && count) { detailInput.addEventListener('input', function() { count.textContent = String(detailInput.value.length); }); } setTimeout(function() { var emailInput = document.getElementById('reporter-email'); if (emailInput) emailInput.focus(); }, 0); } function closeReportModal() { var modal = document.getElementById('report-modal'); if (modal) modal.remove(); document.body.classList.remove('gx-modal-open'); document.body.style.overflow = ''; } function setReportMessage(type, message) { var box = document.getElementById('report-inline-message'); if (!box) return; box.className = 'report-inline-message ' + (type || 'info'); box.textContent = message || ''; box.style.display = message ? 'block' : 'none'; } function submitResourceReport() { var submitBtn = document.getElementById('report-modal-submit'); var reporterName = (document.getElementById('reporter-name')?.value || '').trim(); var reporterEmail = (document.getElementById('reporter-email')?.value || '').trim(); var detail = (document.getElementById('report-detail')?.value || '').trim(); var gameId = getCurrentGameId(); var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!reporterEmail || !emailPattern.test(reporterEmail)) { setReportMessage('error', '请填写有效邮箱,方便处理完成后通知您。'); document.getElementById('reporter-email')?.focus(); return; } if (!detail || detail.length < 3) { setReportMessage('error', '请写清楚反馈的问题,至少 3 个字。'); document.getElementById('report-detail')?.focus(); return; } if (!gameId) { setReportMessage('error', '资源 ID 异常,请刷新页面后重试。'); return; } setReportMessage('info', '正在提交反馈,请稍候...'); if (submitBtn) { submitBtn.disabled = true; submitBtn.classList.add('is-loading'); submitBtn.innerHTML = '提交中...'; } fetch('/api/games/' + encodeURIComponent(gameId) + '/report', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ reporterName: reporterName, reporterEmail: reporterEmail, detail: detail, pageUrl: location.href }) }) .then(function(response) { return response.json().catch(function() { return {}; }).then(function(data) { if (!response.ok) throw new Error(data.message || '反馈提交失败'); return data; }); }) .then(function(data) { setReportMessage('success', data.message || '反馈已提交,站长会尽快处理。'); if (submitBtn) { submitBtn.classList.remove('is-loading'); submitBtn.classList.add('is-success'); submitBtn.innerHTML = '已提交'; } setTimeout(closeReportModal, 1100); }) .catch(function(error) { setReportMessage('error', error.message || '反馈提交失败,请稍后重试。'); if (submitBtn) { submitBtn.disabled = false; submitBtn.classList.remove('is-loading'); submitBtn.innerHTML = '提交反馈'; } }); } // 进入详情页时强制清理任何残留反馈弹窗;反馈框只允许用户点击按钮后打开。 closeReportModal(); window.addEventListener('pageshow', function(evt) { if (evt.persisted) closeReportModal(); }); document.addEventListener('click', function(e) { var reportTrigger = e.target.closest ? e.target.closest('#report-download-btn') : null; if (reportTrigger) { e.preventDefault(); e.stopPropagation(); openReportModal(); return; } if (e.target.closest && e.target.closest('[data-report-dismiss="true"]')) { e.preventDefault(); closeReportModal(); return; } if (e.target.closest && e.target.closest('#report-modal-submit')) { e.preventDefault(); submitResourceReport(); return; } if (e.target.id === 'report-modal') { closeReportModal(); return; } var downloadBtn = e.target.closest('.download-btn'); if (downloadBtn) { var disk = downloadBtn.getAttribute('data-disk'); var gameId = getCurrentGameId(); if (!gameId || !disk) { console.warn('下载参数缺失', { gameId: gameId, disk: disk }); return; } var btn = downloadBtn; if (btn.disabled) return; btn.disabled = true; btn.textContent = '获取中...'; fetch('/api/games/' + gameId + '/download-link', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ disk: disk }) }) .then(function(r) { if (!r.ok) { return r.json().catch(function() { return {}; }).then(function(d) { throw new Error(d.message || '请求失败(' + r.status + ')'); }); } return r.json(); }) .then(function(data) { if (!data.url) { alert(data.message || '下载链接不可用'); btn.disabled = false; btn.textContent = '立即下载'; return; } if (isPC()) { loadQRCode().then(function() { QRCode.toCanvas(qrcode, data.url, { width: 200, margin: 1, color: { dark: '#000000', light: '#FFFFFF' } }, function(error) { if (error) console.error(error); }); downloadModal.classList.add('active'); }).catch(function() { alert('二维码库加载失败,请刷新页面重试'); }); } else { window.location.href = data.url; } btn.disabled = false; btn.textContent = '立即下载'; }) .catch(function(err) { console.error('下载请求失败:', err); alert(err.message || '网络错误,请稍后重试'); btn.disabled = false; btn.textContent = '立即下载'; }); } }); let qrcodeLoaded = false; function loadQRCode() { if (qrcodeLoaded && window.QRCode) { return Promise.resolve(); } return new Promise((resolve, reject) => { const script = document.createElement('script'); let fallbackTried = false; script.onerror = () => { if (fallbackTried) { reject(); return; } fallbackTried = true; script.src = 'https://testingcf.jsdelivr.net/npm/[email protected]/build/qrcode.min.js'; }; script.onload = () => { qrcodeLoaded = true; resolve(); }; script.src = 'https://gcore.jsdelivr.net/npm/[email protected]/build/qrcode.min.js'; document.head.appendChild(script); }); } loadModalSettings(); const imageModal = document.getElementById('image-modal'); const imageModalImg = document.getElementById('image-modal-img'); const imageModalClose = document.getElementById('image-modal-close'); document.getElementById('detail-cover').addEventListener('click', function() { imageModalImg.src = this.src; imageModal.classList.add('active'); }); document.getElementById('detail-images').addEventListener('click', function(e) { if (e.target.tagName === 'IMG') { imageModalImg.src = e.target.src; imageModal.classList.add('active'); } }); imageModalClose.addEventListener('click', function() { imageModal.classList.remove('active'); }); imageModal.addEventListener('click', function(e) { if (e.target === imageModal) { imageModal.classList.remove('active'); } }); document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { imageModal.classList.remove('active'); if (document.getElementById('report-modal')) closeReportModal(); } });