<?php
function safe_text(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function format_size(int $bytes): string
{
    if ($bytes >= 1048576) {
        return round($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return round($bytes / 1024, 2) . ' KB';
    }
    return $bytes . ' B';
}

function build_download_filename_header(string $filename): string
{
    $base = basename($filename);
    $safeBase = str_replace(['"', '\\', "\r", "\n"], '', $base);
    return 'attachment; filename="' . $safeBase . '"; filename*=UTF-8\'\'' . rawurlencode($base);
}

$downloadDir = __DIR__ . '/download';

// Handle file download when ?file= parameter is present
if (isset($_GET['file']) && $_GET['file'] !== '') {
    $requestedFile = $_GET['file'];
    // Prevent directory traversal
    $requestedFile = basename($requestedFile);
    $filePath = $downloadDir . '/' . $requestedFile;

    if (is_file($filePath) && is_readable($filePath)) {
        $fileSize = filesize($filePath);
        $mimeType = null;

        if (function_exists('finfo_open') && function_exists('finfo_file')) {
            $fileInfo = finfo_open(FILEINFO_MIME_TYPE);
            if ($fileInfo !== false) {
                $mimeType = finfo_file($fileInfo, $filePath);
                finfo_close($fileInfo);
            }
        }

        if ($mimeType === null || $mimeType === false || $mimeType === '') {
            $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
            $mimeMap = [
                'exe' => 'application/octet-stream',
                'zip' => 'application/zip',
                'rar' => 'application/vnd.rar',
                '7z' => 'application/x-7z-compressed',
                'apk' => 'application/vnd.android.package-archive',
                'msi' => 'application/octet-stream',
                'dll' => 'application/octet-stream',
                'pdf' => 'application/pdf',
                'png' => 'image/png',
                'jpg' => 'image/jpeg',
                'jpeg' => 'image/jpeg',
                'gif' => 'image/gif',
                'webp' => 'image/webp',
                'svg' => 'image/svg+xml',
                'html' => 'text/html',
                'htm' => 'text/html',
                'txt' => 'text/plain',
                'json' => 'application/json',
                'xml' => 'application/xml',
            ];
            $mimeType = $mimeMap[$extension] ?? 'application/octet-stream';
        }

        // Fallback for exe files
        if ($mimeType === 'application/octet-stream' || substr($requestedFile, -4) === '.exe') {
            $mimeType = 'application/octet-stream';
        }

        $directDownloadUrl = '/download/' . str_replace('%2F', '', rawurlencode($requestedFile));

        // Prefer a direct file URL so browsers do not treat the request as a risky script-mediated download.
        $isDirectFileRequest = isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/download/') === 0;
        if (!$isDirectFileRequest) {
            header('Location: ' . $directDownloadUrl, true, 302);
            header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
            header('Pragma: public');
            exit;
        }

        header('Content-Type: ' . $mimeType);
        header('Content-Disposition: ' . build_download_filename_header($requestedFile));
        header('Content-Length: ' . $fileSize);
        header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
        header('Pragma: public');
        header('X-Content-Type-Options: nosniff');
        header('Accept-Ranges: bytes');
        header('X-Download-Options: noopen');

        // Log download attempt (non-blocking)
        try {
            $logDir = __DIR__ . '/logs';
            if (!is_dir($logDir)) @mkdir($logDir, 0755, true);
            $logFile = $logDir . '/downloads.log';
            $logEntry = [
                'time' => date('c'),
                'ip' => isset($visitor_ip) ? $visitor_ip : (function() { $k=['HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','REMOTE_ADDR']; foreach($k as $h){ if(!empty($_SERVER[$h])){ $ip=$_SERVER[$h]; if(strpos($ip,',')!==false) $ip=explode(',', $ip)[0]; return trim($ip);} } return '0.0.0.0'; })(),
                'country' => $visitor_geo['country'] ?? '',
                'region' => $visitor_geo['region'] ?? '',
                'city' => $visitor_geo['city'] ?? '',
                'isp' => $visitor_geo['isp'] ?? '',
                'file' => $requestedFile,
                'size' => $fileSize,
                'ua' => $_SERVER['HTTP_USER_AGENT'] ?? '',
            ];
            @file_put_contents($logFile, json_encode($logEntry, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND | LOCK_EX);
        } catch (Throwable $e) {
            // ignore logging errors
        }
        readfile($filePath);
        exit;
    } else {
        header('HTTP/1.1 404 Not Found');
        exit('File not found.');
    }
}

// Load admin optimization config (allows toggling showing .bak files)
$optConfigFile = __DIR__ . '/admin/opt-config.json';
$hideBak = true;
if (is_file($optConfigFile)) {
    $cfg = json_decode(@file_get_contents($optConfigFile), true);
    if (is_array($cfg) && array_key_exists('hide_bak', $cfg)) {
        $hideBak = (bool)$cfg['hide_bak'];
    }
}

$files = [];
if (is_dir($downloadDir)) {
    $items = scandir($downloadDir);
    foreach ($items as $item) {
        if ($item === '.' || $item === '..' || $item[0] === '.') continue;
        // Optionally skip backup files with .bak extension so they are not shown in the public list
        if ($hideBak && substr($item, -4) === '.bak') continue;
        $fullPath = $downloadDir . '/' . $item;
        if (is_file($fullPath)) {
            $files[] = [
                'name' => $item,
                'size' => filesize($fullPath),
                'time' => filemtime($fullPath),
            ];
        }
    }
    usort($files, function ($a, $b) { return $b['time'] - $a['time']; });
}

$preferredDownloadFile = 'HelloGPT-Translator-v6.2.6.zip';
$canonicalDownloadFile = $preferredDownloadFile;
$canonicalVersion = '6.2.6';
if ($canonicalDownloadFile !== '' && !is_file($downloadDir . '/' . $canonicalDownloadFile) && !empty($files)) {
    $canonicalDownloadFile = $files[0]['name'];
    preg_match('/(\d+\.\d+\.\d+)/', $canonicalDownloadFile, $versionMatches);
    if (!empty($versionMatches[1])) {
        $canonicalVersion = $versionMatches[1];
    }
}
if (is_file($downloadDir . '/' . $canonicalDownloadFile)) {
    preg_match('/(\d+\.\d+\.\d+)/', $canonicalDownloadFile, $versionMatches);
    if (!empty($versionMatches[1])) {
        $canonicalVersion = $versionMatches[1];
    }
}

// Get visitor IP and geo information (used for admin/monitoring display)
function get_client_ip(): string
{
    $keys = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'];
    foreach ($keys as $k) {
        if (!empty($_SERVER[$k])) {
            $ip = $_SERVER[$k];
            if (strpos($ip, ',') !== false) {
                $ip = explode(',', $ip)[0];
            }
            return trim($ip);
        }
    }
    return '0.0.0.0';
}

function get_geo_info(string $ip): array
{
    $result = ['country' => '未知', 'region' => '未知', 'city' => '未知', 'isp' => ''];
    if ($ip === '0.0.0.0') return $result;
    $url = 'http://ip-api.com/json/' . rawurlencode($ip) . '?fields=status,country,regionName,city,isp';
    $opts = ['http' => ['timeout' => 1, 'method' => 'GET', 'header' => "User-Agent: hellogpt/1.0\r\n"]];
    $ctx = stream_context_create($opts);
    $json = @file_get_contents($url, false, $ctx);
    if ($json) {
        $data = json_decode($json, true);
        if (is_array($data) && ($data['status'] ?? '') === 'success') {
            $result['country'] = $data['country'] ?? '未知';
            $result['region'] = $data['regionName'] ?? '未知';
            $result['city'] = $data['city'] ?? '未知';
            $result['isp'] = $data['isp'] ?? '';
        }
    }
    return $result;
}

$visitor_ip = get_client_ip();
$visitor_geo = get_geo_info($visitor_ip);
?>
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Download | Hello GPT 翻译器</title>
    <meta name="keywords" content="HelloGPT, 官方下载, 翻译器, AI 翻译, 多语言">
    <meta name="description" content="download — 使用 Hello GPT 翻译器快速获得高质量翻译与写作建议，支持多语言。">
    <meta property="og:type" content="website">
    <meta property="og:title" content="HelloGPT 翻译器 — 官方下载中心">
    <meta property="og:description" content="HelloGPT 官方下载中心，提供正式发布的安装包与安装说明。">
    <link rel="canonical" href="https://zh.hellogtp.net/download.php?file=HelloGPT-Translator-v6.2.6.zip">
    <style>
        body {font-family: Arial, sans-serif; margin:0; padding:0; background:#f4f6f8; color:#333;}
        .container {max-width:980px; margin:40px auto; padding:24px;}
        .card {background:#fff; border:1px solid #dde2e7; border-radius:12px; box-shadow:0 12px 30px rgba(0,0,0,.06); padding:28px;}
        h1,h2 {margin:0 0 16px;}
        .btn {display:inline-block; padding:14px 28px; background:#2563eb; color:#fff; border-radius:10px; text-decoration:none; font-weight:bold; transition:background .2s;}
        .btn:hover {background:#1d4ed8;}
        .badge {display:inline-block; background:#eef4ff; color:#1d4ed8; padding:6px 12px; border-radius:999px; font-size:12px; font-weight:bold; margin-bottom:12px;}
        table {width:100%; border-collapse:collapse; margin-top:18px;}
        th,td {padding:12px 10px; border-bottom:1px solid #e2e8f0; text-align:left;}
        th {background:#f8fafc;}
        .note {margin-top:16px; font-size:14px; color:#555;}
        .meta {line-height:1.8; color:#465368; margin-bottom:18px;}
    </style>

<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Download">
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "WebSite", "url": "https://zh.hellogtp.net", "name": "Hello GTP"}</script>
<meta property="og:image" content="https://zh.hellogtp.net/assets/og-download.svg" />
<meta name="twitter:image" content="https://zh.hellogtp.net/assets/og-download.svg" />
</head>
<body>
<div class="container">
    <div class="card">
        <div class="badge">官方 — 下载中心</div>
        <h1>HelloGPT 翻译器 — 官方下载中心</h1>
        <div class="meta">欢迎从 HelloGPT 官方站点下载正式发布的安装包。HelloGPT 为跨境沟通提供中英互译、多语言翻译、网页与文档翻译等功能。请在下载后核对版本号与文件完整性（如提供 SHA256 校验）。</div>
        <div class="note">当前发布版本：<strong>v<?= safe_text($canonicalVersion) ?></strong> ｜ 您的 IP：<strong><?= safe_text($visitor_ip) ?></strong>，地区：<strong><?= safe_text($visitor_geo['country'] . ' ' . $visitor_geo['region'] . ' ' . $visitor_geo['city']) ?></strong><?php if (!empty($visitor_geo['isp'])): ?>，ISP：<?= safe_text($visitor_geo['isp']) ?><?php endif; ?></div>
        <?php if (count($files) === 0): ?>
            <p>当前暂无可下载的文件。</p>
        <?php else: ?>
            <?php $latest = $files[0]; ?>
            <p>当前最新文件：<strong><?= safe_text($latest['name']) ?></strong>（<?= format_size($latest['size']) ?>）</p>
            <?php if ($canonicalDownloadFile !== ''): ?>
                <a class="btn" href="/download.php?file=<?= rawurlencode($canonicalDownloadFile) ?>" target="_blank">下载官方安装包 v<?= safe_text($canonicalVersion) ?></a>
            <?php else: ?>
                <a class="btn" href="/download.php" target="_blank">下载最新发布</a>
            <?php endif; ?>
            <div class="note" style="margin-top:14px;">
                <strong>安装说明：</strong>
                <ol style="margin:8px 0 0 18px; padding:0; color:#444;">
                    <li>下载后请先校验文件完整性并确认来源为本站。</li>
                    <li>Windows 用户运行安装程序或解压后按照安装向导操作；移动设备请使用对应平台安装包。</li>
                    <li>如遇问题，请参阅帮助文档或通过站点联系我们获取支持。</li>
                </ol>
            </div>
            <h2>历次发布记录</h2>
            <table>
                <thead>
                    <tr><th>文件名</th><th>大小</th><th>更新时间</th><th>下载</th></tr>
                </thead>
                <tbody>
                <?php foreach ($files as $f): ?>
                    <tr>
                        <td><?= safe_text($f['name']) ?></td>
                        <td><?= format_size($f['size']) ?></td>
                        <td><?= date('Y-m-d H:i:s', $f['time']) ?></td>
                        <td><a href="/download.php?file=<?= rawurlencode($f['name']) ?>">下载</a></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
            <p class="note">以上文件均由本站直接提供。若需技术支持或报告问题，请访问主页或反馈渠道。</p>
        <?php endif; ?>
    </div>
</div>
</body>
</html>

