Compare commits

..

8 Commits

Author SHA1 Message Date
ikun0014
839e922d79 2.0.7 2025-09-20 18:57:20 +08:00
ikun0014
2bd2f23838 Update version to v2.0.7 and remove license section
Bumped the displayed version in about.html from v2.0.6 to v2.0.7. Removed the commented-out project license agreement section from README.md for clarity.
2025-09-20 18:57:15 +08:00
ikun0014
9e68621e76 Remove 'verify=False' from HTTP client instantiations
Eliminated the 'verify=False' parameter from all httpx.Client and httpx.AsyncClient initializations to enforce SSL certificate verification. This improves security by ensuring HTTPS requests validate server certificates.
2025-09-20 18:56:29 +08:00
ikun0014
2a6a9421ca Refactor IP location check and update HTTP client config
Moved the IP location check logic to constants.py and set IS_CN at import time, removing the async check_ip method from OnekeyApp. Updated all httpx client instantiations to use verify=False for SSL verification. Adjusted imports and usages accordingly in web/app.py and main.py.
2025-09-20 18:55:49 +08:00
ikun0014
1a6cf47882 Refactor constants and update HTTP client config
Added type annotations to constants in constants.py and set IS_CN default to True. Updated main.py to use 'flag' instead of 'ip_flag' from API response. Removed 'verify=False' and 'proxy=None' from httpx.AsyncClient initialization in client.py for improved security and clarity.
2025-09-20 18:32:28 +08:00
ikun0014
09f94c5f11 2.0.6 2025-09-19 22:48:25 +08:00
ikun0014
5307dc0766 Update about.html 2025-09-19 22:48:24 +08:00
ikun0014
15b3caddcf Add region-based CDN selection and IP check
Introduces an IS_CN flag and logic to select Steam CDN endpoints based on region in constants.py. Adds an IP check in OnekeyApp to set the region flag at runtime. Also removes a commercial use warning from about.html and applies minor formatting changes to index.html.
2025-09-19 22:46:53 +08:00
7 changed files with 177 additions and 189 deletions

View File

@@ -47,20 +47,6 @@ git clone https://github.com/ikunshare/Onekey
pip install -r requirements.txt
```
<!-- ## 项目协议
本项目基于 GPL-2.0 许可证发行,以下协议是对于 GPL-2.0 原协议的补充,如有冲突,以以下协议为准。
词语约定: “使用者”指签署本协议的使用者;“版权数据”指包括但不限于图像、音频、名字等在内的他人拥有所属版权的数据。
本项目的数据来源原理是从Steam官方的CDN服务器中拉取游戏清单数据经过对数据简单地筛选与合并后进行展示因此本项目不对数据的准确性负责。
使用本项目的过程中可能会产生版权数据对于这些版权数据本项目不拥有它们的所有权为了避免造成侵权使用者务必在24 小时内清除使用本项目的过程中所产生的版权数据。
由于使用本项目产生的包括由于本协议或由于使用或无法使用本项目而引起的任何性质的任何直接、间接、特殊、偶然或结果性损害(包括但不限于因商誉损失、停工、计算机故障或故障引起的损害赔偿,或任何及所有其他商业损害或损失)由使用者负责。
本项目完全免费,且开源发布于 GitHub 面向全世界人用作对技术的学习交流,本项目不对项目内的技术可能存在违反当地法律法规的行为作保证,禁止在违反当地法律法规的情况下使用本项目,对于使用者在明知或不知当地法律法规不允许的情况下使用本项目所造成的任何违法违规行为由使用者承担,本项目不承担由此造成的任何直接、间接、特殊、偶然或结果性责任。
而且,本项目已禁止使用于商业用途,以及不得进行未经允许的二次修改,否则必须同时发布源代码。
若你使用了本项目,将代表你接受以上协议。
Steam正版平台不易请尊重版权支持正版。
本项目仅用于对技术可行性的探索及研究,不接受任何商业(包括但不限于广告等)合作。 -->
## Star 趋势图

View File

@@ -1,6 +1,6 @@
{
"name": "onekey",
"version": "2.0.5",
"version": "2.0.7",
"description": "一个Steam仓库清单下载器",
"main": "index.js",
"scripts": {

View File

@@ -1,20 +1,50 @@
"""常量定义"""
from pathlib import Path
from httpx import Client
LOG_DIR = Path("logs")
CONFIG_FILE = Path("config.json")
LOG_DIR: Path = Path("logs")
CONFIG_FILE: Path = Path("config.json")
STEAM_API_BASE = "https://steam.ikunshare.com/api"
STEAM_CACHE_CDN_LIST = [
"https://cache1-hkg1.steamcontent.com",
"https://cache2-hkg1.steamcontent.com",
"https://cache3-hkg1.steamcontent.com",
"https://cache4-hkg1.steamcontent.com",
"https://cache5-hkg1.steamcontent.com",
"https://cache6-hkg1.steamcontent.com",
"https://cache7-hkg1.steamcontent.com",
"https://cache8-hkg1.steamcontent.com",
"https://cache9-hkg1.steamcontent.com",
"https://cache10-hkg1.steamcontent.com",
]
def check_ip():
try:
with Client(timeout=5.0) as client:
req = client.get(
"https://mips.kugou.com/check/iscn",
)
req.raise_for_status()
body = req.json()
print("已获取IP属地")
return bool(body["flag"])
except:
print("获取IP属地失败, 默认您位于中国大陆境内")
return True
IS_CN: bool = check_ip()
STEAM_API_BASE: str = "https://steam.ikunshare.com/api"
STEAM_CACHE_CDN_LIST: list = (
[
"http://alibaba.cdn.steampipe.steamcontent.com",
"http://steampipe.steamcontent.tnkjmec.com",
]
if IS_CN
else [
"http://fastly.cdn.steampipe.steamcontent.com",
"http://akamai.cdn.steampipe.steamcontent.com",
"http://telus.cdn.steampipe.steamcontent.com",
"https://cache1-hkg1.steamcontent.com",
"https://cache2-hkg1.steamcontent.com",
"https://cache3-hkg1.steamcontent.com",
"https://cache4-hkg1.steamcontent.com",
"https://cache5-hkg1.steamcontent.com",
"https://cache6-hkg1.steamcontent.com",
"https://cache7-hkg1.steamcontent.com",
"https://cache8-hkg1.steamcontent.com",
"https://cache9-hkg1.steamcontent.com",
"https://cache10-hkg1.steamcontent.com",
]
)

View File

@@ -8,7 +8,7 @@ class HttpClient:
"""HTTP客户端封装"""
def __init__(self):
self._client = httpx.AsyncClient(verify=False, timeout=60, proxy=None)
self._client = httpx.AsyncClient(timeout=60.0)
async def get(self, url: str, headers: Optional[Dict] = None) -> httpx.Response:
"""GET请求"""

View File

@@ -13,6 +13,7 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from src import constants
from src.constants import STEAM_API_BASE

View File

@@ -26,7 +26,7 @@
<p class="project-subtitle">直观,优雅的游戏解锁解决方案</p>
</div>
<div class="project-version">
<span class="version-label">v2.0.5</span>
<span class="version-label">v2.0.7</span>
<span class="version-type">Web UI</span>
</div>
</div>
@@ -106,10 +106,6 @@
<h4>使用须知</h4>
</div>
<div class="notice-content">
<p>
<strong>⚠️ 重要提醒</strong> -
本工具完全免费,严禁任何形式的商业化使用或倒卖
</p>
<p>
<strong>🖥️ 系统要求</strong> - 请确保已安装Windows
10/11并正确配置Steam客户端

View File

@@ -1,175 +1,150 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Onekey - Home</title>
<!-- Material Design 3 -->
<link
href="https://cdn.jsdmirror.com/gh/ikun0014/font@main/style.css"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Onekey - Home</title>
<!-- 自定义样式 -->
<link rel="stylesheet" href="/static/css/style.css" />
</head>
<!-- Material Design 3 -->
<link href="https://cdn.jsdmirror.com/gh/ikun0014/font@main/style.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<body>
<div class="app-container">
<!-- 顶部应用栏 -->
<header class="app-bar">
<div class="app-bar-content">
<span class="material-icons app-icon">games</span>
<h1 class="app-title">Onekey</h1>
<button
type="button"
class="theme-toggle"
id="themeToggle"
title="切换主题"
>
<span class="material-icons">light_mode</span>
</button>
<a href="/settings" class="btn btn-text settings-link">
<span class="material-icons">settings</span>
<span class="settings-text">设置</span>
</a>
<a href="/about" class="btn btn-text about-link">
<span class="material-icons">info</span>
<span class="about-text">关于本项目</span>
</a>
<!-- 自定义样式 -->
<link rel="stylesheet" href="/static/css/style.css" />
</head>
<body>
<div class="app-container">
<!-- 顶部应用栏 -->
<header class="app-bar">
<div class="app-bar-content">
<span class="material-icons app-icon">games</span>
<h1 class="app-title">Onekey</h1>
<button type="button" class="theme-toggle" id="themeToggle" title="切换主题">
<span class="material-icons">light_mode</span>
</button>
<a href="/settings" class="btn btn-text settings-link">
<span class="material-icons">settings</span>
<span class="settings-text">设置</span>
</a>
<a href="/about" class="btn btn-text about-link">
<span class="material-icons">info</span>
<span class="about-text">关于本项目</span>
</a>
</div>
</header>
<!-- 主内容区域 -->
<main class="main-content">
<!-- 配置状态卡片 -->
<div class="card config-card">
<div class="card-header">
<span class="material-icons">settings</span>
<h2>配置状态</h2>
</div>
</header>
<!-- 主内容区域 -->
<main class="main-content">
<!-- 配置状态卡片 -->
<div class="card config-card">
<div class="card-header">
<span class="material-icons">settings</span>
<h2>配置状态</h2>
<div class="card-content">
<div class="config-status" id="configStatus">
<div class="loading">正在检查配置...</div>
</div>
<div class="card-content">
<div class="config-status" id="configStatus">
<div class="loading">正在检查配置...</div>
</div>
</div>
<!-- 游戏解锁卡片 -->
<div class="card unlock-card">
<div class="card-header">
<span class="material-icons">lock_open</span>
<h2>游戏解锁</h2>
</div>
<div class="card-content">
<form id="unlockForm" class="unlock-form">
<div class="input-group">
<label for="appId" class="input-label">Steam App ID</label>
<input type="text" id="appId" name="appId" class="text-field" placeholder="请输入游戏的App ID"
inputmode="numeric" autocomplete="off" autofocus required />
<div class="input-feedback" id="appIdFeedback"></div>
<div class="input-helper">例如: 730 (CS2), 570 (Dota 2)</div>
</div>
</div>
</div>
<!-- 游戏解锁卡片 -->
<div class="card unlock-card">
<div class="card-header">
<span class="material-icons">lock_open</span>
<h2>游戏解锁</h2>
</div>
<div class="card-content">
<form id="unlockForm" class="unlock-form">
<div class="input-group">
<label for="appId" class="input-label">Steam App ID</label>
<input
type="text"
id="appId"
name="appId"
class="text-field"
placeholder="请输入游戏的App ID"
inputmode="numeric"
autocomplete="off"
autofocus
required
/>
<div class="input-feedback" id="appIdFeedback"></div>
<div class="input-helper">例如: 730 (CS2), 570 (Dota 2)</div>
</div>
<div class="input-group">
<label class="input-label">解锁工具</label>
<div class="radio-group">
<label class="radio-item">
<input
type="radio"
name="toolType"
value="steamtools"
checked
/>
<span class="radio-button"></span>
<span class="radio-label"
>SteamTools(更新积极, 推荐使用)</span
>
</label>
<label class="radio-item">
<input type="radio" name="toolType" value="greenluma" />
<span class="radio-button"></span>
<span class="radio-label">GreenLuma(一年一更, 无GUI)</span>
</label>
</div>
</div>
<div class="input-group" id="+DLCGroup">
<label class="checkbox-item">
<input type="checkbox" id="+DLC" name="+DLC" />
<span class="checkbox-button"></span>
<span class="checkbox-label">检索并入库所有DLC</span>
<div class="input-group">
<label class="input-label">解锁工具</label>
<div class="radio-group">
<label class="radio-item">
<input type="radio" name="toolType" value="steamtools" checked />
<span class="radio-button"></span>
<span class="radio-label">SteamTools(更新积极, 推荐使用)</span>
</label>
<label class="radio-item">
<input type="radio" name="toolType" value="greenluma" />
<span class="radio-button"></span>
<span class="radio-label">GreenLuma(一年一更, 无GUI)</span>
</label>
<div class="input-helper">
需要注意: 有些DLC的Depot与游戏本体在一起, 不会分离
</div>
</div>
</div>
<div class="button-group">
<button type="submit" class="btn btn-primary" id="unlockBtn">
<span class="material-icons">play_arrow</span>
开始解锁
</button>
<button type="button" class="btn btn-secondary" id="resetBtn">
<span class="material-icons">refresh</span>
重置
</button>
<div class="input-group" id="+DLCGroup">
<label class="checkbox-item">
<input type="checkbox" id="+DLC" name="+DLC" />
<span class="checkbox-button"></span>
<span class="checkbox-label">检索并入库所有DLC</span>
</label>
<div class="input-helper">
需要注意: 有些DLC的Depot与游戏本体在一起, 不会分离
</div>
</form>
</div>
</div>
</div>
<!-- 进度日志卡片 -->
<div class="card progress-card">
<div class="card-header">
<span class="material-icons">timeline</span>
<h2>执行日志</h2>
<div class="card-actions">
<button class="btn btn-text" id="clearLogBtn">
<span class="material-icons">clear_all</span>
清空
<div class="button-group">
<button type="submit" class="btn btn-primary" id="unlockBtn">
<span class="material-icons">play_arrow</span>
开始解锁
</button>
<button type="button" class="btn btn-secondary" id="resetBtn">
<span class="material-icons">refresh</span>
重置
</button>
</div>
</form>
</div>
</div>
<!-- 进度日志卡片 -->
<div class="card progress-card">
<div class="card-header">
<span class="material-icons">timeline</span>
<h2>执行日志</h2>
<div class="card-actions">
<button class="btn btn-text" id="clearLogBtn">
<span class="material-icons">clear_all</span>
清空
</button>
</div>
<div class="card-content">
<div class="progress-container" id="progressContainer">
<div class="progress-placeholder">
<span class="material-icons">info</span>
<p>等待任务开始...</p>
</div>
</div>
<div class="card-content">
<div class="progress-container" id="progressContainer">
<div class="progress-placeholder">
<span class="material-icons">info</span>
<p>等待任务开始...</p>
</div>
</div>
</div>
</main>
</div>
<!-- 提示框 -->
<div id="snackbar" class="snackbar">
<div class="snackbar-content">
<span id="snackbarMessage"></span>
<button id="snackbarClose" class="snackbar-action">
<span class="material-icons">close</span>
</button>
</div>
</div>
</main>
</div>
<!-- 脚本 -->
<script src="{{ url_for('static', path='js/app.js') }}"></script>
<script src="{{ url_for('static', path='js/theme.js') }}"></script>
<script src="{{ url_for('static', path='js/project-info.js') }}"></script>
</body>
</html>
<!-- 提示框 -->
<div id="snackbar" class="snackbar">
<div class="snackbar-content">
<span id="snackbarMessage"></span>
<button id="snackbarClose" class="snackbar-action">
<span class="material-icons">close</span>
</button>
</div>
</div>
<!-- 脚本 -->
<script src="{{ url_for('static', path='js/app.js') }}"></script>
<script src="{{ url_for('static', path='js/theme.js') }}"></script>
<script src="{{ url_for('static', path='js/project-info.js') }}"></script>
</body>
</html>