docs(readme): update readme

This commit is contained in:
MingxuanGame
2025-08-22 10:06:26 +00:00
parent fdd57c54f7
commit a0b76bbde3
6 changed files with 101 additions and 359 deletions

View File

@@ -1,94 +1,107 @@
# 数据库设置 # see https://github.com/GooGuTeam/g0v0-server/wiki/Configuration
# Database Settings
MYSQL_HOST="localhost" MYSQL_HOST="localhost"
MYSQL_PORT=3306 MYSQL_PORT=3306
MYSQL_DATABASE="osu_api" MYSQL_DATABASE="osu_api"
MYSQL_USER="osu_api" MYSQL_USER="osu_api"
MYSQL_PASSWORD="password" MYSQL_PASSWORD="password"
MYSQL_ROOT_PASSWORD="password" MYSQL_ROOT_PASSWORD="password"
# Redis URL
REDIS_URL="redis://127.0.0.1:6379/0" REDIS_URL="redis://127.0.0.1:6379/0"
# JWT 密钥,使用 openssl rand -hex 32 生成 # JWT Settings
# Use `openssl rand -hex 32` to generate a secure key
JWT_SECRET_KEY="your_jwt_secret_here" JWT_SECRET_KEY="your_jwt_secret_here"
# JWT 算法
ALGORITHM="HS256" ALGORITHM="HS256"
# JWT 过期时间
ACCESS_TOKEN_EXPIRE_MINUTES=1440 ACCESS_TOKEN_EXPIRE_MINUTES=1440
# 服务器地址 # OAuth Settings
OSU_CLIENT_ID=5
OSU_CLIENT_SECRET="FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
OSU_WEB_CLIENT_ID=6
# Use `openssl rand -hex 40` to generate a secure key
OSU_WEB_CLIENT_SECRET="your_osu_web_client_secret_here"
# Server Settings
HOST="0.0.0.0" HOST="0.0.0.0"
PORT=8000 PORT=8000
# 服务器 URL
SERVER_URL="http://localhost:8000"
# 额外的 CORS 允许的域名列表
CORS_URLS='[]'
# 前端 URL当访问从游戏打开的 URL 时会重定向到这个 URL为空表示不重定向
FRONTEND_URL
# 调试模式,生产环境请设置为 false
DEBUG=false DEBUG=false
CORS_URLS='[]'
SERVER_URL="http://localhost:8000"
FRONTEND_URL=
# osu! 登录设置 # SignalR Settings
OSU_CLIENT_ID=5 # lazer client ID
OSU_CLIENT_SECRET="FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk" # lazer client secret
OSU_WEB_CLIENT_ID=6 # 网页端 client ID
OSU_WEB_CLIENT_SECRET="your_osu_web_client_secret_here" # 网页端 client secret使用 openssl rand -hex 40 生成
# SignalR 服务器设置
SIGNALR_NEGOTIATE_TIMEOUT=30 SIGNALR_NEGOTIATE_TIMEOUT=30
SIGNALR_PING_INTERVAL=15 SIGNALR_PING_INTERVAL=15
# Fetcher 设置 # Fetcher Settings
FETCHER_CLIENT_ID="" FETCHER_CLIENT_ID=""
FETCHER_CLIENT_SECRET="" FETCHER_CLIENT_SECRET=""
FETCHER_SCOPES=public FETCHER_SCOPES="public"
# 日志设置 # Logging Settings
LOG_LEVEL="INFO" LOG_LEVEL="INFO"
# 邮件服务设置 # Email Service Settings
SMTP_SERVER="smtp.gmail.com" # SMTP 服务器地址 ENABLE_EMAIL_VERIFICATION=false
SMTP_PORT=587 # SMTP 端口 SMTP_SERVER="localhost"
SMTP_USERNAME="your-email@gmail.com" # 邮箱用户名 SMTP_PORT=587
SMTP_PASSWORD="your-app-password" # 邮箱密码或应用专用密码 SMTP_USERNAME=""
FROM_EMAIL="noreply@your-server.com" # 发送方邮箱 SMTP_PASSWORD=""
FROM_NAME="osu! Private Server" # 发送方名称 FROM_EMAIL="noreply@example.com"
FROM_NAME="osu! server"
# 邮件验证功能开关 # Sentry Configuration
ENABLE_EMAIL_VERIFICATION=true # 是否启用邮件验证功能(新位置登录时需要邮件验证) SENTRY_DSN=
ENABLE_EMAIL_SENDING=false # 是否真实发送邮件false时仅模拟发送输出到日志
# Sentry 设置,为空表示不启用 # New Relic Configuration
SENTRY_DSN NEW_RELIC_ENVIRONMENT=
# GeoIP 配置 - MaxMind License Key用于 IP 地址地理位置查询) # GeoIP Configuration
MAXMIND_LICENSE_KEY="" MAXMIND_LICENSE_KEY=""
# GeoIP 数据库存储目录
GEOIP_DEST_DIR="./geoip" GEOIP_DEST_DIR="./geoip"
# GeoIP 每周更新的星期几0=周一6=周日)
GEOIP_UPDATE_DAY=1 GEOIP_UPDATE_DAY=1
# GeoIP 每周更新时间小时0-23
GEOIP_UPDATE_HOUR=2 GEOIP_UPDATE_HOUR=2
# 游戏设置 # Game Settings
ENABLE_RX=false # 启用 RX mod 统计数据 ENABLE_RX=false
ENABLE_AP=false # 启用 AP mod Z统计数据 ENABLE_AP=false
ENABLE_ALL_MODS_PP=false # 启用所有 Mod 的 PP 计算 ENABLE_ALL_MODS_PP=false
ENABLE_SUPPORTER_FOR_ALL_USERS=false # 启用所有新注册用户的支持者状态 ENABLE_SUPPORTER_FOR_ALL_USERS=false
ENABLE_ALL_BEATMAP_LEADERBOARD=false # 启用所有谱面的排行榜(没有排行榜的谱面会以 APPROVED 状态返回) ENABLE_ALL_BEATMAP_LEADERBOARD=false
ENABLE_ALL_BEATMAP_PP=false # 允许任何谱面获得 PP ENABLE_ALL_BEATMAP_PP=false
SUSPICIOUS_SCORE_CHECK=true # 是否检查可疑的分数,默认开启 SEASONAL_BACKGROUNDS='[]'
SEASONAL_BACKGROUNDS='[]' # 季节背景图 URL 列表
BANNED_NAME='["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]' # 禁止使用的用户名列表
# 存储服务设置 # Beatmap Cache Settings
# 支持的存储类型local本地存储、r2Cloudflare R2、s3AWS S3 ENABLE_BEATMAP_PRELOAD=true
BEATMAP_CACHE_EXPIRE_HOURS=24
# Ranking Cache Settings
ENABLE_RANKING_CACHE=true
RANKING_CACHE_EXPIRE_MINUTES=10
RANKING_CACHE_REFRESH_INTERVAL_MINUTES=10
RANKING_CACHE_MAX_PAGES=20
RANKING_CACHE_TOP_COUNTRIES=20
# User Cache Settings
ENABLE_USER_CACHE_PRELOAD=true
USER_CACHE_EXPIRE_SECONDS=300
USER_SCORES_CACHE_EXPIRE_SECONDS=60
USER_BEATMAPSETS_CACHE_EXPIRE_SECONDS=600
USER_CACHE_MAX_PRELOAD_USERS=200
USER_CACHE_CONCURRENT_LIMIT=10
# Anti-cheat Settings
SUSPICIOUS_SCORE_CHECK=true
BANNED_NAME='["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]'
# Storage Settings
# Supported storage services: local, r2, s3
STORAGE_SERVICE="local" STORAGE_SERVICE="local"
# 存储服务配置 (JSON 格式) # Local Storage Settings (when STORAGE_SERVICE=local)
# 本地存储配置(当 STORAGE_SERVICE=local 时) # STORAGE_SETTINGS='{"local_storage_path": "./storage"}'
STORAGE_SETTINGS='{"local_storage_path": "./storage"}'
# Cloudflare R2 存储配置(当 STORAGE_SERVICE=r2 时) # Cloudflare R2 Storage Settings (when STORAGE_SERVICE=r2)
# STORAGE_SETTINGS='{ # STORAGE_SETTINGS='{
# "r2_account_id": "your_cloudflare_r2_account_id", # "r2_account_id": "your_cloudflare_r2_account_id",
# "r2_access_key_id": "your_r2_access_key_id", # "r2_access_key_id": "your_r2_access_key_id",
@@ -97,11 +110,10 @@ STORAGE_SETTINGS='{"local_storage_path": "./storage"}'
# "r2_public_url_base": "https://your-custom-domain.com" # "r2_public_url_base": "https://your-custom-domain.com"
# }' # }'
# AWS S3 存储配置(当 STORAGE_SERVICE=s3 时) # AWS S3 Storage Settings (when STORAGE_SERVICE=s3)
# STORAGE_SETTINGS='{ # STORAGE_SETTINGS='{
# "s3_access_key_id": "your_aws_access_key_id", # "s3_access_key_id": "your_aws_access_key_id",
# "s3_secret_access_key": "your_aws_secret_access_key", # "s3_secret_access_key": "your_aws_secret_access_key",
# "s3_bucket_name": "your_s3_bucket_name", # "s3_bucket_name": "your_s3_bucket_name",
# "s3_region_name": "us-east-1", # "s3_region_name": "us-east-1",
# "s3_public_url_base": "https://your-custom-domain.com" # "s3_public_url_base": "https://your-custom
# }'

View File

@@ -25,7 +25,7 @@ This is an osu! API server implemented with FastAPI + MySQL + Redis, supporting
``` ```
2. Create a `.env` file 2. Create a `.env` file
Please see the server configuration below to modify the .env file. Please see [wiki](https://github.com/GooGuTeam/g0v0-server/wiki/Configuration) to modify the .env file.
```bash ```bash
cp .env.example .env cp .env.example .env
``` ```
@@ -40,131 +40,6 @@ This is an osu! API server implemented with FastAPI + MySQL + Redis, supporting
Use a [custom osu!lazer client](https://github.com/GooGuTeam/osu), or use [LazerAuthlibInjection](https://github.com/MingxuanGame/LazerAuthlibInjection), and change the server settings to the server's address. Use a [custom osu!lazer client](https://github.com/GooGuTeam/osu), or use [LazerAuthlibInjection](https://github.com/MingxuanGame/LazerAuthlibInjection), and change the server settings to the server's address.
## Configuration
### Database Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `MYSQL_HOST` | MySQL host address | `localhost` |
| `MYSQL_PORT` | MySQL port | `3306` |
| `MYSQL_DATABASE` | MySQL database name | `osu_api` |
| `MYSQL_USER` | MySQL username | `osu_api` |
| `MYSQL_PASSWORD` | MySQL password | `password` |
| `MYSQL_ROOT_PASSWORD` | MySQL root password | `password` |
| `REDIS_URL` | Redis connection string | `redis://127.0.0.1:6379/0` |
### JWT Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `JWT_SECRET_KEY` | JWT signing key | `your_jwt_secret_here` |
| `ALGORITHM` | JWT algorithm | `HS256` |
| `ACCESS_TOKEN_EXPIRE_MINUTES` | Access token expiration time (minutes) | `1440` |
### Server Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `HOST` | Server listening address | `0.0.0.0` |
| `PORT` | Server listening port | `8000` |
| `DEBUG` | Debug mode | `false` |
| `SERVER_URL` | Server URL | `http://localhost:8000` |
| `CORS_URLS` | Additional CORS allowed domain list (JSON format) | `[]` |
| `FRONTEND_URL` | Frontend URL, redirects to this URL when accessing URLs opened from the game. Empty means no redirection. | `(null)` |
### OAuth Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `OSU_CLIENT_ID` | OAuth client ID | `5` |
| `OSU_CLIENT_SECRET` | OAuth client secret | `FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk` |
| `OSU_WEB_CLIENT_ID` | Web OAuth client ID | `6` |
| `OSU_WEB_CLIENT_SECRET` | Web OAuth client secret | `your_osu_web_client_secret_here` |
### SignalR Server Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `SIGNALR_NEGOTIATE_TIMEOUT` | SignalR negotiation timeout (seconds) | `30` |
| `SIGNALR_PING_INTERVAL` | SignalR ping interval (seconds) | `15` |
### Fetcher Settings
The Fetcher is used to get data from the official osu! API using OAuth 2.0 authentication.
| Variable Name | Description | Default Value |
|---|---|---|
| `FETCHER_CLIENT_ID` | Fetcher client ID | `""` |
| `FETCHER_CLIENT_SECRET` | Fetcher client secret | `""` |
| `FETCHER_SCOPES` | Fetcher scopes | `public` |
### Log Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `LOG_LEVEL` | Log level | `INFO` |
### Sentry Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `SENTRY_DSN` | Sentry DSN, empty to disable Sentry | `(null)` |
### Game Settings
| Variable Name | Description | Default Value |
|---|---|---|
| `ENABLE_RX` | Enable RX mod statistics | `false` |
| `ENABLE_AP` | Enable AP mod statistics | `false` |
| `ENABLE_ALL_MODS_PP` | Enable PP calculation for all mods | `false` |
| `ENABLE_SUPPORTER_FOR_ALL_USERS` | Enable supporter status for all new users | `false` |
| `ENABLE_ALL_BEATMAP_LEADERBOARD` | Enable leaderboards for all beatmaps | `false` |
| `ENABLE_ALL_BEATMAP_PP` | Allow any beatmap to grant PP | `false` |
| `SUSPICIOUS_SCORE_CHECK` | Enable suspicious score check (star>25 & acc<80 or pp>2300) | `true` |
| `SEASONAL_BACKGROUNDS` | List of seasonal background URLs | `[]` |
| `BANNED_NAME` | List of banned usernames | `["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]` |
### Storage Service Settings
Used for storing replay files, avatars, and other static assets.
| Variable Name | Description | Default Value |
|---|---|---|
| `STORAGE_SERVICE` | Storage service type: `local`, `r2`, `s3` | `local` |
| `STORAGE_SETTINGS` | Storage service configuration (JSON format), see below for configuration | `{"local_storage_path": "./storage"}` |
## Storage Service Configuration
### Local Storage (Recommended for development)
Local storage saves files to the server's local filesystem, suitable for development and small-scale deployments.
```bash
STORAGE_SERVICE="local"
STORAGE_SETTINGS='{"local_storage_path": "./storage"}'
```
### Cloudflare R2 Storage (Recommended for production)
```bash
STORAGE_SERVICE="r2"
STORAGE_SETTINGS='{
"r2_account_id": "your_cloudflare_account_id",
"r2_access_key_id": "your_r2_access_key_id",
"r2_secret_access_key": "your_r2_secret_access_key",
"r2_bucket_name": "your_bucket_name",
"r2_public_url_base": "https://your-custom-domain.com"
}'
```
### AWS S3 Storage
```bash
STORAGE_SERVICE="s3"
STORAGE_SETTINGS='{
"s3_access_key_id": "your_aws_access_key_id",
"s3_secret_access_key": "your_aws_secret_access_key",
"s3_bucket_name": "your_s3_bucket_name",
"s3_region_name": "us-east-1",
"s3_public_url_base": "https://your-custom-domain.com"
}'
```
> **Note**: In a production environment, be sure to change the default keys and passwords!
### Updating the Database ### Updating the Database
Refer to the [Database Migration Guide](https://github.com/GooGuTeam/g0v0-server/wiki/Migrate-Database) Refer to the [Database Migration Guide](https://github.com/GooGuTeam/g0v0-server/wiki/Migrate-Database)
@@ -177,6 +52,8 @@ MIT License
The project is currently in a state of rapid iteration. Issues and Pull Requests are welcome! The project is currently in a state of rapid iteration. Issues and Pull Requests are welcome!
See [Contributing Guide](./CONTRIBUTING.md) for more information.
## Discussion ## Discussion
- Discord: https://discord.gg/AhzJXXWYfF - Discord: https://discord.gg/AhzJXXWYfF

143
README.md
View File

@@ -26,7 +26,7 @@ cd g0v0-server
2. 创建 `.env` 文件 2. 创建 `.env` 文件
请参考下方的服务器配置修改 .env 文件 请参考 [wiki](https://github.com/GooGuTeam/g0v0-server/wiki/Configuration) 来修改 `.env` 文件
```bash ```bash
cp .env.example .env cp .env.example .env
@@ -44,145 +44,6 @@ docker-compose -f docker-compose-osurx.yml up -d
使用[自定义的 osu!lazer 客户端](https://github.com/GooGuTeam/osu),或者使用 [LazerAuthlibInjection](https://github.com/MingxuanGame/LazerAuthlibInjection),修改服务器设置为服务器的 IP 使用[自定义的 osu!lazer 客户端](https://github.com/GooGuTeam/osu),或者使用 [LazerAuthlibInjection](https://github.com/MingxuanGame/LazerAuthlibInjection),修改服务器设置为服务器的 IP
## 环境变量配置
### 数据库设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `MYSQL_HOST` | MySQL 主机地址 | `localhost` |
| `MYSQL_PORT` | MySQL 端口 | `3306` |
| `MYSQL_DATABASE` | MySQL 数据库名 | `osu_api` |
| `MYSQL_USER` | MySQL 用户名 | `osu_api` |
| `MYSQL_PASSWORD` | MySQL 密码 | `password` |
| `MYSQL_ROOT_PASSWORD` | MySQL root 密码 | `password` |
| `REDIS_URL` | Redis 连接字符串 | `redis://127.0.0.1:6379/0` |
### JWT 设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `JWT_SECRET_KEY` | JWT 签名密钥 | `your_jwt_secret_here` |
| `ALGORITHM` | JWT 算法 | `HS256` |
| `ACCESS_TOKEN_EXPIRE_MINUTES` | 访问令牌过期时间(分钟) | `1440` |
### 服务器设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `HOST` | 服务器监听地址 | `0.0.0.0` |
| `PORT` | 服务器监听端口 | `8000` |
| `DEBUG` | 调试模式 | `false` |
| `SERVER_URL` | 服务器 URL | `http://localhost:8000` |
| `CORS_URLS` | 额外的 CORS 允许的域名列表 (JSON 格式) | `[]` |
| `FRONTEND_URL` | 前端 URL当访问从游戏打开的 URL 时会重定向到这个 URL为空表示不重定向 | `(null)` |
### OAuth 设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `OSU_CLIENT_ID` | OAuth 客户端 ID | `5` |
| `OSU_CLIENT_SECRET` | OAuth 客户端密钥 | `FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk` |
| `OSU_WEB_CLIENT_ID` | Web OAuth 客户端 ID | `6` |
| `OSU_WEB_CLIENT_SECRET` | Web OAuth 客户端密钥 | `your_osu_web_client_secret_here`
### SignalR 服务器设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `SIGNALR_NEGOTIATE_TIMEOUT` | SignalR 协商超时时间(秒) | `30` |
| `SIGNALR_PING_INTERVAL` | SignalR ping 间隔(秒) | `15` |
### Fetcher 设置
Fetcher 用于从 osu! 官方 API 获取数据,使用 osu! 官方 API 的 OAuth 2.0 认证
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `FETCHER_CLIENT_ID` | Fetcher 客户端 ID | `""` |
| `FETCHER_CLIENT_SECRET` | Fetcher 客户端密钥 | `""` |
| `FETCHER_SCOPES` | Fetcher 权限范围 | `public` |
### 日志设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `LOG_LEVEL` | 日志级别 | `INFO` |
### Sentry 设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `SENTRY_DSN` | Sentry DSN为空不启用 Sentry | `(null)` |
### GeoIP 配置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `MAXMIND_LICENSE_KEY` | MaxMind License Key用于下载离线IP库 | `""` |
| `GEOIP_DEST_DIR` | GeoIP 数据库存储目录 | `"./geoip"` |
| `GEOIP_UPDATE_DAY` | GeoIP 每周更新的星期几0=周一6=周日) | `1` |
| `GEOIP_UPDATE_HOUR` | GeoIP 每周更新时间小时0-23 | `2` |
### New Relic 设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `NEW_RELIC_ENVIRONMENT` | New Relic 环境标识 | `"production"``"development"` |
`newrelic.ini` 配置文件放入项目根目录即可自动启用 New Relic 监控。如果配置文件不存在或 newrelic 包未安装,将跳过 New Relic 初始化。可通过环境变量 `NEW_RELIC_ENVIRONMENT` 指定运行环境。
### 游戏设置
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `ENABLE_RX` | 启用 RX mod 统计数据 | `false` |
| `ENABLE_AP` | 启用 AP mod 统计数据 | `false` |
| `ENABLE_ALL_MODS_PP` | 启用所有 Mod 的 PP 计算 | `false` |
| `ENABLE_SUPPORTER_FOR_ALL_USERS` | 启用所有新注册用户的支持者状态 | `false` |
| `ENABLE_ALL_BEATMAP_LEADERBOARD` | 启用所有谱面的排行榜 | `false` |
| `ENABLE_ALL_BEATMAP_PP` | 允许任何谱面获得 PP | `false` |
| `SUSPICIOUS_SCORE_CHECK` | 启用可疑分数检查star>25&acc<80 或 pp>2300 | `true` |
| `SEASONAL_BACKGROUNDS` | 季节背景图 URL 列表 | `[]` |
| `BANNED_NAME` | 禁止使用的用户名列表 | `["mrekk", "vaxei", "btmc", "cookiezi", "peppy", "saragi", "chocomint"]` |
### 存储服务设置
用于存储回放文件、头像等静态资源。
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `STORAGE_SERVICE` | 存储服务类型:`local``r2``s3` | `local` |
| `STORAGE_SETTINGS` | 存储服务配置 (JSON 格式),配置见下 | `{"local_storage_path": "./storage"}` |
## 存储服务配置
### 本地存储 (推荐用于开发环境)
本地存储将文件保存在服务器的本地文件系统中,适合开发和小规模部署。
```bash
STORAGE_SERVICE="local"
STORAGE_SETTINGS='{"local_storage_path": "./storage"}'
```
### Cloudflare R2 存储 (推荐用于生产环境)
```bash
STORAGE_SERVICE="r2"
STORAGE_SETTINGS='{
"r2_account_id": "your_cloudflare_account_id",
"r2_access_key_id": "your_r2_access_key_id",
"r2_secret_access_key": "your_r2_secret_access_key",
"r2_bucket_name": "your_bucket_name",
"r2_public_url_base": "https://your-custom-domain.com"
}'
```
### AWS S3 存储
```bash
STORAGE_SERVICE="s3"
STORAGE_SETTINGS='{
"s3_access_key_id": "your_aws_access_key_id",
"s3_secret_access_key": "your_aws_secret_access_key",
"s3_bucket_name": "your_s3_bucket_name",
"s3_region_name": "us-east-1",
"s3_public_url_base": "https://your-custom-domain.com"
}'
```
> **注意**: 在生产环境中,请务必更改默认的密钥和密码!
### 更新数据库 ### 更新数据库
@@ -196,6 +57,8 @@ MIT License
项目目前处于快速迭代状态,欢迎提交 Issue 和 Pull Request 项目目前处于快速迭代状态,欢迎提交 Issue 和 Pull Request
查看 [贡献指南](./CONTRIBUTING.md) 获取更多信息。
## 参与讨论 ## 参与讨论
- QQ 群:`1059561526` - QQ 群:`1059561526`

View File

@@ -118,6 +118,7 @@ class Settings(BaseSettings):
log_level: str = "INFO" log_level: str = "INFO"
# 邮件服务设置 # 邮件服务设置
enable_email_verification: bool = Field(default=False, description="是否启用邮件验证功能")
smtp_server: str = "localhost" smtp_server: str = "localhost"
smtp_port: int = 587 smtp_port: int = 587
smtp_username: str = "" smtp_username: str = ""
@@ -125,13 +126,12 @@ class Settings(BaseSettings):
from_email: str = "noreply@example.com" from_email: str = "noreply@example.com"
from_name: str = "osu! server" from_name: str = "osu! server"
# 邮件验证功能开关
enable_email_verification: bool = Field(default=True, description="是否启用邮件验证功能")
enable_email_sending: bool = Field(default=False, description="是否真实发送邮件False时仅模拟发送")
# Sentry 配置 # Sentry 配置
sentry_dsn: HttpUrl | None = None sentry_dsn: HttpUrl | None = None
# New Relic 配置
new_relic_environment: None | str = None
# GeoIP 配置 # GeoIP 配置
maxmind_license_key: str = "" maxmind_license_key: str = ""
geoip_dest_dir: str = "./geoip" geoip_dest_dir: str = "./geoip"
@@ -145,11 +145,11 @@ class Settings(BaseSettings):
enable_supporter_for_all_users: bool = False enable_supporter_for_all_users: bool = False
enable_all_beatmap_leaderboard: bool = False enable_all_beatmap_leaderboard: bool = False
enable_all_beatmap_pp: bool = False enable_all_beatmap_pp: bool = False
# 性能优化设置 seasonal_backgrounds: Annotated[list[str], BeforeValidator(_parse_list)] = []
# 谱面缓存设置
enable_beatmap_preload: bool = True enable_beatmap_preload: bool = True
beatmap_cache_expire_hours: int = 24 beatmap_cache_expire_hours: int = 24
max_concurrent_pp_calculations: int = 10
enable_pp_calculation_threading: bool = True
# 排行榜缓存设置 # 排行榜缓存设置
enable_ranking_cache: bool = True enable_ranking_cache: bool = True
@@ -168,7 +168,6 @@ class Settings(BaseSettings):
# 反作弊设置 # 反作弊设置
suspicious_score_check: bool = True suspicious_score_check: bool = True
seasonal_backgrounds: Annotated[list[str], BeforeValidator(_parse_list)] = []
banned_name: list[str] = [ banned_name: list[str] = [
"mrekk", "mrekk",
"vaxei", "vaxei",

View File

@@ -140,12 +140,6 @@ class EmailService:
msg.attach(MIMEText(html_content, "html", "utf-8")) msg.attach(MIMEText(html_content, "html", "utf-8"))
# 发送邮件
if not settings.enable_email_sending:
# 邮件发送功能禁用时只记录日志,不实际发送
logger.info(f"[Email Verification] Mock sending verification code to {email}: {code}")
return True
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server: with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
if self.smtp_username and self.smtp_password: if self.smtp_username and self.smtp_password:
server.starttls() server.starttls()

39
main.py
View File

@@ -4,6 +4,7 @@ import asyncio
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from datetime import datetime from datetime import datetime
import os import os
from pathlib import Path
from app.config import settings from app.config import settings
from app.dependencies.database import engine, redis_client from app.dependencies.database import engine, redis_client
@@ -42,27 +43,6 @@ from app.service.redis_message_system import redis_message_system
from app.service.stats_scheduler import start_stats_scheduler, stop_stats_scheduler from app.service.stats_scheduler import start_stats_scheduler, stop_stats_scheduler
from app.utils import bg_tasks from app.utils import bg_tasks
# 检查 New Relic 配置文件是否存在,如果存在则初始化 New Relic
newrelic_config_path = os.path.join(os.path.dirname(__file__), "newrelic.ini")
if os.path.exists(newrelic_config_path):
try:
import newrelic.agent
environment = os.environ.get(
"NEW_RELIC_ENVIRONMENT",
"production" if not settings.debug else "development",
)
newrelic.agent.initialize(newrelic_config_path, environment)
logger.info(f"[NewRelic] Enabled, environment: {environment}")
except ImportError:
logger.warning("[NewRelic] Config file found but 'newrelic' package is not installed")
except Exception as e:
logger.error(f"[NewRelic] Initialization failed: {e}")
else:
logger.info("[NewRelic] No newrelic.ini config file found, skipping initialization")
from fastapi import FastAPI, HTTPException, Request from fastapi import FastAPI, HTTPException, Request
from fastapi.exceptions import RequestValidationError from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
@@ -110,6 +90,23 @@ desc = (
"V1 API 文档:[osu-api](https://github.com/ppy/osu-api/wiki)" "V1 API 文档:[osu-api](https://github.com/ppy/osu-api/wiki)"
) )
# 检查 New Relic 配置文件是否存在,如果存在则初始化 New Relic
newrelic_config_path = Path("newrelic.ini")
if newrelic_config_path.exists():
try:
import newrelic.agent
environment = settings.new_relic_environment or ("production" if not settings.debug else "development")
newrelic.agent.initialize(newrelic_config_path, environment)
logger.info(f"[NewRelic] Enabled, environment: {environment}")
except ImportError:
logger.warning("[NewRelic] Config file found but 'newrelic' package is not installed")
except Exception as e:
logger.error(f"[NewRelic] Initialization failed: {e}")
else:
logger.info("[NewRelic] No newrelic.ini config file found, skipping initialization")
if settings.sentry_dsn is not None: if settings.sentry_dsn is not None:
sentry_sdk.init( sentry_sdk.init(
dsn=str(settings.sentry_dsn), dsn=str(settings.sentry_dsn),