mirror of
https://github.com/m1ngsama/automa.git
synced 2025-12-24 10:51:20 +00:00
refactor: 重构Minecraft服务器自动化管理方案
## 重构内容 ### 新增自动化脚本系统 (scripts/) - utils.sh: 通用工具库(日志、Docker操作、备份、网络检查) - setup.sh: 环境初始化脚本(目录结构、权限、配置验证) - mod-manager.sh: Mods管理(Modrinth下载、更新、清理) - backup.sh: 备份管理(世界/配置/mods备份、恢复、清理) - monitor.sh: 服务器监控(状态、资源、玩家、日志分析) ### 增强Makefile集成 新增命令: - minecraft-status: 服务器状态检查 - minecraft-setup: 环境初始化 - minecraft-mods-*: Mods管理命令 - minecraft-backup-*: 备份管理命令 ### 完善文档 - 重写README: 详细的使用指南、故障排查、迁移指南 - 新增CHANGELOG: 完整的重构说明和技术细节 ## 架构改进 ### 整合原有设计 - 继承src/automatic/的日志系统设计 - 改进Modrinth API集成逻辑 - 优化部署流程和备份机制 ### 新增优势 - Docker优先的容器化方案 - 模块化脚本设计,职责单一 - Makefile统一管理入口 - 完整的生命周期自动化 ## 技术特性 - 完善的错误处理和日志记录 - macOS/Linux跨平台兼容 - 敏感信息安全管理 - 持续监控模式 ## 向后兼容 - 保留src/automatic/旧脚本(供参考) - 配置文件格式完全兼容 - Docker Compose配置无变化
This commit is contained in:
parent
4ff60014df
commit
0fe7ed79ad
8 changed files with 2098 additions and 16 deletions
47
Makefile
47
Makefile
|
|
@ -16,10 +16,19 @@ help:
|
|||
@echo " all-down Stop all services"
|
||||
@echo ""
|
||||
@echo "Service-specific Commands:"
|
||||
@echo " minecraft-up Start Minecraft server"
|
||||
@echo " minecraft-down Stop Minecraft server"
|
||||
@echo " minecraft-logs View Minecraft logs"
|
||||
@echo " minecraft-restart Restart Minecraft server"
|
||||
@echo " Minecraft:"
|
||||
@echo " minecraft-up Start Minecraft server"
|
||||
@echo " minecraft-down Stop Minecraft server"
|
||||
@echo " minecraft-logs View Minecraft logs"
|
||||
@echo " minecraft-restart Restart Minecraft server"
|
||||
@echo " minecraft-status Show server status"
|
||||
@echo " minecraft-setup Initialize environment"
|
||||
@echo " minecraft-mods-download Download mods from Modrinth"
|
||||
@echo " minecraft-mods-list List installed mods"
|
||||
@echo " minecraft-mods-update Update all mods"
|
||||
@echo " minecraft-backup Create full backup"
|
||||
@echo " minecraft-backup-world Backup world data only"
|
||||
@echo " minecraft-backup-list List available backups"
|
||||
@echo ""
|
||||
@echo " teamspeak-up Start TeamSpeak server"
|
||||
@echo " teamspeak-down Stop TeamSpeak server"
|
||||
|
|
@ -87,6 +96,36 @@ minecraft-restart:
|
|||
@cd minecraft && docker compose restart
|
||||
@echo "✓ Minecraft server restarted"
|
||||
|
||||
minecraft-status:
|
||||
@cd minecraft && ./scripts/monitor.sh status
|
||||
|
||||
minecraft-setup:
|
||||
@cd minecraft && ./scripts/setup.sh
|
||||
|
||||
minecraft-mods-download:
|
||||
@cd minecraft && ./scripts/mod-manager.sh download
|
||||
|
||||
minecraft-mods-list:
|
||||
@cd minecraft && ./scripts/mod-manager.sh list
|
||||
|
||||
minecraft-mods-update:
|
||||
@cd minecraft && ./scripts/mod-manager.sh update
|
||||
|
||||
minecraft-mods-check:
|
||||
@cd minecraft && ./scripts/mod-manager.sh check
|
||||
|
||||
minecraft-backup:
|
||||
@cd minecraft && ./scripts/backup.sh backup all
|
||||
|
||||
minecraft-backup-world:
|
||||
@cd minecraft && ./scripts/backup.sh backup world
|
||||
|
||||
minecraft-backup-list:
|
||||
@cd minecraft && ./scripts/backup.sh list
|
||||
|
||||
minecraft-backup-cleanup:
|
||||
@cd minecraft && ./scripts/backup.sh cleanup
|
||||
|
||||
# TeamSpeak
|
||||
teamspeak-up:
|
||||
@cd teamspeak && docker compose up -d
|
||||
|
|
|
|||
184
minecraft/CHANGELOG.md
Normal file
184
minecraft/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
# Minecraft 自动化方案重构日志
|
||||
|
||||
## 2025-12-09 - 自动化架构重构
|
||||
|
||||
### 🎯 重构目标
|
||||
|
||||
整合原有的本地部署方案(`src/automatic/`)和 Docker Compose 方案,提供统一的自动化管理系统。
|
||||
|
||||
### ✨ 新增功能
|
||||
|
||||
#### 1. 统一的脚本体系
|
||||
|
||||
创建 `scripts/` 目录,包含以下模块:
|
||||
|
||||
- **utils.sh** - 通用工具库
|
||||
- 彩色日志输出
|
||||
- Docker 环境检查
|
||||
- 容器状态管理
|
||||
- 文件备份工具
|
||||
- 网络连接检测
|
||||
|
||||
- **setup.sh** - 环境初始化
|
||||
- 系统环境检查
|
||||
- 目录结构初始化
|
||||
- 配置文件验证
|
||||
- 权限自动修复
|
||||
|
||||
- **mod-manager.sh** - Mods 管理
|
||||
- 从 Modrinth 自动下载
|
||||
- 批量更新 mods
|
||||
- 列出已安装 mods
|
||||
- 清理和状态检查
|
||||
|
||||
- **backup.sh** - 备份管理
|
||||
- 世界数据备份
|
||||
- 配置文件备份
|
||||
- Mods 备份
|
||||
- 备份恢复功能
|
||||
- 自动清理旧备份
|
||||
|
||||
- **monitor.sh** - 服务器监控
|
||||
- 容器状态检查
|
||||
- 资源使用监控
|
||||
- 在线玩家查询
|
||||
- 日志分析
|
||||
- 持续监控模式
|
||||
|
||||
#### 2. Makefile 集成
|
||||
|
||||
在根目录 `Makefile` 中新增命令:
|
||||
|
||||
**服务器管理**
|
||||
- `make minecraft-status` - 查看服务器状态
|
||||
- `make minecraft-setup` - 初始化环境
|
||||
|
||||
**Mods 管理**
|
||||
- `make minecraft-mods-download` - 下载 mods
|
||||
- `make minecraft-mods-list` - 列出 mods
|
||||
- `make minecraft-mods-update` - 更新 mods
|
||||
- `make minecraft-mods-check` - 检查状态
|
||||
|
||||
**备份管理**
|
||||
- `make minecraft-backup` - 完整备份
|
||||
- `make minecraft-backup-world` - 备份世界
|
||||
- `make minecraft-backup-list` - 列出备份
|
||||
- `make minecraft-backup-cleanup` - 清理备份
|
||||
|
||||
#### 3. 完整的文档
|
||||
|
||||
重写 `minecraft/README.md`:
|
||||
- 详细的快速开始指南
|
||||
- 完整的命令参考
|
||||
- 高级用法示例
|
||||
- 故障排查指南
|
||||
- 迁移指南
|
||||
|
||||
### 🔄 架构改进
|
||||
|
||||
#### 从旧方案继承的优点
|
||||
|
||||
1. **日志系统**
|
||||
- 保留了 `logger.sh` 的彩色输出设计
|
||||
- 增强了日志功能(系统信息、时间戳、文件记录)
|
||||
|
||||
2. **Mods 下载逻辑**
|
||||
- 基于 `download-mods.sh` 改进
|
||||
- 统一使用 `extras/mods.txt` 格式
|
||||
- 增加错误处理和重试机制
|
||||
|
||||
3. **部署流程**
|
||||
- 参考 `deploy.sh` 的备份逻辑
|
||||
- 适配 Docker Compose 环境
|
||||
|
||||
#### 新增的优势
|
||||
|
||||
1. **Docker 优先**
|
||||
- 完全容器化部署
|
||||
- 一致的运行环境
|
||||
- 简化依赖管理
|
||||
|
||||
2. **模块化设计**
|
||||
- 每个脚本职责单一
|
||||
- 通过 `utils.sh` 共享通用功能
|
||||
- 易于维护和扩展
|
||||
|
||||
3. **统一管理**
|
||||
- Makefile 统一入口
|
||||
- 一致的命令格式
|
||||
- 与其他服务(TeamSpeak、Nextcloud)集成
|
||||
|
||||
### 📂 目录变更
|
||||
|
||||
```
|
||||
旧结构:
|
||||
minecraft/
|
||||
├── src/automatic/
|
||||
│ ├── deploy.sh
|
||||
│ ├── download-mods.sh
|
||||
│ ├── logger.sh
|
||||
│ └── requirements.txt
|
||||
|
||||
新结构:
|
||||
minecraft/
|
||||
├── scripts/ # 新增:统一的脚本目录
|
||||
│ ├── utils.sh
|
||||
│ ├── setup.sh
|
||||
│ ├── mod-manager.sh
|
||||
│ ├── backup.sh
|
||||
│ └── monitor.sh
|
||||
├── extras/
|
||||
│ └── mods.txt # 统一的 mods 配置
|
||||
├── backups/ # 新增:自动备份目录
|
||||
├── logs/ # 新增:脚本日志目录
|
||||
└── src/automatic/ # 保留(供参考)
|
||||
```
|
||||
|
||||
### 🔧 技术细节
|
||||
|
||||
1. **错误处理**
|
||||
- 所有脚本使用 `set -e`
|
||||
- 完善的返回码检查
|
||||
- 详细的错误消息
|
||||
|
||||
2. **跨平台兼容**
|
||||
- macOS 和 Linux 兼容的命令
|
||||
- 自动检测 `docker compose` vs `docker-compose`
|
||||
- 处理不同的 `stat` 命令格式
|
||||
|
||||
3. **安全性**
|
||||
- 敏感信息通过 `.env` 管理
|
||||
- RCON 密码验证
|
||||
- 备份前的确认机制
|
||||
|
||||
### 📋 迁移建议
|
||||
|
||||
如果使用旧的 `src/automatic/` 脚本:
|
||||
|
||||
1. 旧脚本仍可使用(未删除)
|
||||
2. 建议迁移到新的 Docker 方案
|
||||
3. 新方案提供更多自动化功能
|
||||
4. 通过 Makefile 统一管理更便捷
|
||||
|
||||
### 🎯 后续计划
|
||||
|
||||
- [ ] 添加定时备份的 systemd/cron 模板
|
||||
- [ ] 集成 Prometheus 指标监控
|
||||
- [ ] 添加自动更新检查
|
||||
- [ ] Web 控制面板集成
|
||||
- [ ] 多服务器管理支持
|
||||
|
||||
### 📝 配置兼容性
|
||||
|
||||
- ✅ `docker-compose.yml` - 无变化
|
||||
- ✅ `.env` - 无变化
|
||||
- ✅ `configs/` - 无变化
|
||||
- ✅ `mods/` - 无变化
|
||||
- ✅ `extras/mods.txt` - 格式与旧 `requirements.txt` 兼容
|
||||
|
||||
### 🙏 致谢
|
||||
|
||||
重构整合了原有设计的精华:
|
||||
- 日志系统的设计理念
|
||||
- Modrinth API 集成逻辑
|
||||
- 部署流程的最佳实践
|
||||
|
|
@ -1,15 +1,316 @@
|
|||
# Automa Minecraft
|
||||
# Automa Minecraft 服务器
|
||||
|
||||
基于 Docker Compose 的 Minecraft Fabric 1.21.1 服务器,提供完整的自动化管理方案。
|
||||
|
||||
## 📁 目录结构
|
||||
|
||||
```
|
||||
mc-fabric-docker/
|
||||
├── docker-compose.yml
|
||||
├── .env # 必改:UID、GID、RCON_PASSWORD、TZ
|
||||
├── mods/ # 放你的所有 mods jar
|
||||
├── configs/
|
||||
│ ├── server.properties # 服务器配置
|
||||
│ ├── whitelist.json # 白名单(示例)
|
||||
│ └── ops.json # OP(示例)
|
||||
├── data/ # 自动生成:世界、备份、日志
|
||||
└── extras/
|
||||
└── mods.txt # 可选:Modrinth 自动下载模组
|
||||
minecraft/
|
||||
├── docker-compose.yml # Docker Compose 配置
|
||||
├── .env # 环境变量配置(需自定义)
|
||||
├── configs/ # 服务器配置文件
|
||||
│ ├── server.properties # 服务器属性配置
|
||||
│ └── whitelist.json # 白名单配置
|
||||
├── mods/ # Mods 存放目录
|
||||
├── data/ # 持久化数据(世界、日志等)
|
||||
├── backups/ # 自动备份目录
|
||||
├── logs/ # 自动化脚本日志
|
||||
├── extras/
|
||||
│ └── mods.txt # Modrinth Mods 列表
|
||||
└── scripts/ # 自动化脚本
|
||||
├── utils.sh # 工具库
|
||||
├── setup.sh # 环境初始化
|
||||
├── mod-manager.sh # Mods 管理
|
||||
├── backup.sh # 备份管理
|
||||
└── monitor.sh # 服务器监控
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 环境初始化
|
||||
|
||||
```bash
|
||||
# 检查环境并初始化目录结构
|
||||
make minecraft-setup
|
||||
```
|
||||
|
||||
### 2. 配置服务器
|
||||
|
||||
编辑 `.env` 文件,设置必要的配置:
|
||||
|
||||
```bash
|
||||
# 用户权限(使用 id 命令查看)
|
||||
UID=1000
|
||||
GID=1000
|
||||
|
||||
# RCON 密码(远程管理)
|
||||
RCON_PASSWORD=your_secure_password
|
||||
|
||||
# 时区
|
||||
TZ=Asia/Shanghai
|
||||
```
|
||||
|
||||
### 3. 下载 Mods(可选)
|
||||
|
||||
```bash
|
||||
# 从 Modrinth 下载 mods(根据 extras/mods.txt)
|
||||
make minecraft-mods-download
|
||||
|
||||
# 或手动将 mods 放入 mods/ 目录
|
||||
```
|
||||
|
||||
### 4. 启动服务器
|
||||
|
||||
```bash
|
||||
# 启动服务器
|
||||
make minecraft-up
|
||||
|
||||
# 查看日志
|
||||
make minecraft-logs
|
||||
```
|
||||
|
||||
## 📋 常用命令
|
||||
|
||||
### 服务器管理
|
||||
|
||||
```bash
|
||||
make minecraft-up # 启动服务器
|
||||
make minecraft-down # 停止服务器
|
||||
make minecraft-restart # 重启服务器
|
||||
make minecraft-logs # 查看实时日志
|
||||
make minecraft-status # 查看服务器状态
|
||||
```
|
||||
|
||||
### Mods 管理
|
||||
|
||||
```bash
|
||||
make minecraft-mods-download # 下载所有 mods
|
||||
make minecraft-mods-list # 列出已安装的 mods
|
||||
make minecraft-mods-update # 更新所有 mods
|
||||
make minecraft-mods-check # 检查 mods 状态
|
||||
```
|
||||
|
||||
Mods 配置在 `extras/mods.txt` 中,每行一个 Modrinth slug:
|
||||
|
||||
```
|
||||
fabric-api
|
||||
sodium
|
||||
lithium
|
||||
iris
|
||||
```
|
||||
|
||||
### 备份管理
|
||||
|
||||
```bash
|
||||
make minecraft-backup # 完整备份(世界、配置、mods)
|
||||
make minecraft-backup-world # 仅备份世界数据
|
||||
make minecraft-backup-list # 列出所有备份
|
||||
make minecraft-backup-cleanup # 清理旧备份
|
||||
```
|
||||
|
||||
备份存储在 `backups/` 目录,按类型分类:
|
||||
- `backups/worlds/` - 世界数据备份
|
||||
- `backups/configs/` - 配置文件备份
|
||||
- `backups/mods/` - Mods 备份
|
||||
|
||||
## 🔧 高级用法
|
||||
|
||||
### 直接使用脚本
|
||||
|
||||
所有自动化脚本位于 `scripts/` 目录:
|
||||
|
||||
```bash
|
||||
# 环境初始化
|
||||
./scripts/setup.sh
|
||||
|
||||
# Mods 管理
|
||||
./scripts/mod-manager.sh download # 下载 mods
|
||||
./scripts/mod-manager.sh list # 列出 mods
|
||||
./scripts/mod-manager.sh update # 更新 mods
|
||||
./scripts/mod-manager.sh clean # 清理 mods
|
||||
|
||||
# 备份管理
|
||||
./scripts/backup.sh backup all # 完整备份
|
||||
./scripts/backup.sh backup world # 仅备份世界
|
||||
./scripts/backup.sh list # 列出备份
|
||||
./scripts/backup.sh restore <file> # 恢复备份
|
||||
./scripts/backup.sh cleanup 10 # 保留最近10个备份
|
||||
|
||||
# 服务器监控
|
||||
./scripts/monitor.sh status # 完整状态
|
||||
./scripts/monitor.sh resources # 资源使用
|
||||
./scripts/monitor.sh players # 在线玩家
|
||||
./scripts/monitor.sh logs 50 # 最近50行日志
|
||||
./scripts/monitor.sh watch 10 # 持续监控(每10秒)
|
||||
```
|
||||
|
||||
### 自定义配置
|
||||
|
||||
#### 修改服务器配置
|
||||
|
||||
编辑 `configs/server.properties`,然后重启服务器:
|
||||
|
||||
```bash
|
||||
vim configs/server.properties
|
||||
make minecraft-restart
|
||||
```
|
||||
|
||||
#### 添加新 Mods
|
||||
|
||||
1. 在 Modrinth 找到 mod 的 slug(URL中的ID)
|
||||
2. 添加到 `extras/mods.txt`
|
||||
3. 运行下载命令:
|
||||
|
||||
```bash
|
||||
make minecraft-mods-download
|
||||
make minecraft-restart
|
||||
```
|
||||
|
||||
#### 配置白名单
|
||||
|
||||
编辑 `configs/whitelist.json`,并在 `.env` 或 `configs/server.properties` 中启用白名单:
|
||||
|
||||
```properties
|
||||
white-list=true
|
||||
enforce-whitelist=true
|
||||
```
|
||||
|
||||
## 🔍 监控与维护
|
||||
|
||||
### 实时监控
|
||||
|
||||
```bash
|
||||
# 查看完整状态(容器、资源、玩家、错误)
|
||||
make minecraft-status
|
||||
|
||||
# 持续监控模式(每5秒刷新)
|
||||
cd minecraft && ./scripts/monitor.sh watch 5
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
|
||||
```bash
|
||||
# 查看 Docker 容器日志
|
||||
make minecraft-logs
|
||||
|
||||
# 查看自动化脚本日志
|
||||
ls -lh logs/
|
||||
tail -f logs/automation-*.log
|
||||
```
|
||||
|
||||
### 定期备份
|
||||
|
||||
建议配置 cron 任务定期备份:
|
||||
|
||||
```bash
|
||||
# 每天凌晨3点备份世界数据
|
||||
0 3 * * * cd /path/to/automa && make minecraft-backup-world
|
||||
|
||||
# 每周清理旧备份(保留最近10个)
|
||||
0 4 * * 0 cd /path/to/automa/minecraft && ./scripts/backup.sh cleanup 10
|
||||
```
|
||||
|
||||
## 📊 性能优化
|
||||
|
||||
项目已包含性能优化 mods:
|
||||
- **Sodium** - 渲染优化
|
||||
- **Lithium** - 服务器性能优化
|
||||
- **Iris** - 着色器支持
|
||||
|
||||
内存配置在 `docker-compose.yml` 中:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
MEMORY: "4G" # 最大内存
|
||||
INIT_MEMORY: "2G" # 初始内存
|
||||
```
|
||||
|
||||
## 🛡️ 安全建议
|
||||
|
||||
1. **修改 RCON 密码**:在 `.env` 中设置强密码
|
||||
2. **配置防火墙**:仅开放必要端口(25565, 25575)
|
||||
3. **启用白名单**:在 `configs/server.properties` 中配置
|
||||
4. **定期备份**:使用自动化备份脚本
|
||||
5. **监控日志**:定期检查错误日志
|
||||
|
||||
## 🔄 迁移指南
|
||||
|
||||
### 从旧版本迁移
|
||||
|
||||
如果你使用的是 `src/automatic/` 下的旧脚本:
|
||||
|
||||
1. 新方案使用 Docker Compose,更易部署和维护
|
||||
2. Mods 管理统一使用 `extras/mods.txt` 格式
|
||||
3. 所有自动化功能集成到 `scripts/` 目录
|
||||
4. 通过 Makefile 统一管理
|
||||
|
||||
迁移步骤:
|
||||
|
||||
```bash
|
||||
# 1. 备份旧数据
|
||||
cp -r old_server_dir/world minecraft/data/
|
||||
|
||||
# 2. 复制 mods(如果手动管理)
|
||||
cp -r old_mods_dir/* minecraft/mods/
|
||||
|
||||
# 3. 初始化新环境
|
||||
make minecraft-setup
|
||||
|
||||
# 4. 启动服务器
|
||||
make minecraft-up
|
||||
```
|
||||
|
||||
## 📝 故障排查
|
||||
|
||||
### 容器无法启动
|
||||
|
||||
```bash
|
||||
# 检查 Docker 服务
|
||||
docker info
|
||||
|
||||
# 查看容器日志
|
||||
make minecraft-logs
|
||||
|
||||
# 检查环境配置
|
||||
cat .env
|
||||
```
|
||||
|
||||
### Mods 下载失败
|
||||
|
||||
```bash
|
||||
# 检查网络连接
|
||||
curl -I https://api.modrinth.com
|
||||
|
||||
# 查看详细日志
|
||||
cat logs/automation-*.log
|
||||
|
||||
# 手动下载 mods 放入 mods/ 目录
|
||||
```
|
||||
|
||||
### 性能问题
|
||||
|
||||
```bash
|
||||
# 查看资源使用
|
||||
cd minecraft && ./scripts/monitor.sh resources
|
||||
|
||||
# 调整内存配置
|
||||
vim docker-compose.yml # 修改 MEMORY 和 INIT_MEMORY
|
||||
|
||||
# 重启服务器
|
||||
make minecraft-restart
|
||||
```
|
||||
|
||||
## 📚 相关资源
|
||||
|
||||
- [Docker 文档](https://docs.docker.com/)
|
||||
- [itzg/minecraft-server 镜像](https://github.com/itzg/docker-minecraft-server)
|
||||
- [Modrinth](https://modrinth.com/) - Mods 下载平台
|
||||
- [Fabric](https://fabricmc.net/) - Mod 加载器
|
||||
|
||||
## 🤝 贡献
|
||||
|
||||
欢迎提交 Issue 和 Pull Request!
|
||||
|
||||
## 📄 许可
|
||||
|
||||
MIT License
|
||||
|
|
|
|||
376
minecraft/scripts/backup.sh
Executable file
376
minecraft/scripts/backup.sh
Executable file
|
|
@ -0,0 +1,376 @@
|
|||
#!/usr/bin/env bash
|
||||
# Minecraft 服务器备份管理
|
||||
# 支持世界数据、配置文件、mods 的备份和恢复
|
||||
|
||||
set -e
|
||||
|
||||
# 加载工具库
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/utils.sh"
|
||||
|
||||
# ============================================
|
||||
# 配置变量
|
||||
# ============================================
|
||||
readonly PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
readonly BACKUP_DIR="$PROJECT_ROOT/backups"
|
||||
readonly DATA_DIR="$PROJECT_ROOT/data"
|
||||
readonly MODS_DIR="$PROJECT_ROOT/mods"
|
||||
readonly CONFIGS_DIR="$PROJECT_ROOT/configs"
|
||||
readonly CONTAINER_NAME="mc-fabric-1.21.1"
|
||||
|
||||
# ============================================
|
||||
# 备份函数
|
||||
# ============================================
|
||||
|
||||
# 备份世界数据
|
||||
backup_world() {
|
||||
log_info "备份世界数据..."
|
||||
|
||||
local world_dir="$DATA_DIR/world"
|
||||
|
||||
if [[ ! -d "$world_dir" ]]; then
|
||||
log_warning "世界数据不存在: $world_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 通知服务器保存
|
||||
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log_info "通知服务器保存世界..."
|
||||
docker exec "$CONTAINER_NAME" rcon-cli save-all flush 2>/dev/null || true
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# 创建备份
|
||||
local backup_file=$(create_backup "$world_dir" "$BACKUP_DIR/worlds")
|
||||
|
||||
if [[ -n "$backup_file" ]]; then
|
||||
log_success "世界备份完成"
|
||||
return 0
|
||||
else
|
||||
log_error "世界备份失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 备份配置文件
|
||||
backup_configs() {
|
||||
log_info "备份配置文件..."
|
||||
|
||||
if [[ ! -d "$CONFIGS_DIR" ]]; then
|
||||
log_warning "配置目录不存在: $CONFIGS_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local backup_file=$(create_backup "$CONFIGS_DIR" "$BACKUP_DIR/configs")
|
||||
|
||||
if [[ -n "$backup_file" ]]; then
|
||||
log_success "配置备份完成"
|
||||
return 0
|
||||
else
|
||||
log_error "配置备份失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 备份 mods
|
||||
backup_mods() {
|
||||
log_info "备份 Mods..."
|
||||
|
||||
if [[ ! -d "$MODS_DIR" || -z "$(ls -A "$MODS_DIR" 2>/dev/null)" ]]; then
|
||||
log_warning "Mods 目录为空"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local backup_file=$(create_backup "$MODS_DIR" "$BACKUP_DIR/mods")
|
||||
|
||||
if [[ -n "$backup_file" ]]; then
|
||||
log_success "Mods 备份完成"
|
||||
return 0
|
||||
else
|
||||
log_error "Mods 备份失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 完整备份
|
||||
backup_all() {
|
||||
log_info "开始完整备份..."
|
||||
log_separator
|
||||
|
||||
local success=0
|
||||
local failed=0
|
||||
|
||||
# 备份世界
|
||||
if backup_world; then
|
||||
((success++))
|
||||
else
|
||||
((failed++))
|
||||
fi
|
||||
|
||||
log_separator
|
||||
|
||||
# 备份配置
|
||||
if backup_configs; then
|
||||
((success++))
|
||||
else
|
||||
((failed++))
|
||||
fi
|
||||
|
||||
log_separator
|
||||
|
||||
# 备份 mods
|
||||
if backup_mods; then
|
||||
((success++))
|
||||
else
|
||||
((failed++))
|
||||
fi
|
||||
|
||||
log_separator
|
||||
log_info "备份完成 - 成功: $success, 失败: $failed"
|
||||
|
||||
return $failed
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 恢复函数
|
||||
# ============================================
|
||||
|
||||
# 列出可用备份
|
||||
list_backups() {
|
||||
local type="${1:-all}"
|
||||
|
||||
log_info "可用备份:"
|
||||
|
||||
case "$type" in
|
||||
world | worlds)
|
||||
list_backup_type "worlds" "世界数据"
|
||||
;;
|
||||
config | configs)
|
||||
list_backup_type "configs" "配置文件"
|
||||
;;
|
||||
mods)
|
||||
list_backup_type "mods" "Mods"
|
||||
;;
|
||||
all | *)
|
||||
list_backup_type "worlds" "世界数据"
|
||||
list_backup_type "configs" "配置文件"
|
||||
list_backup_type "mods" "Mods"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 列出特定类型的备份
|
||||
list_backup_type() {
|
||||
local subdir="$1"
|
||||
local name="$2"
|
||||
local backup_path="$BACKUP_DIR/$subdir"
|
||||
|
||||
echo ""
|
||||
log_info "=== $name ==="
|
||||
|
||||
if [[ ! -d "$backup_path" ]]; then
|
||||
log_warning "无可用备份"
|
||||
return
|
||||
fi
|
||||
|
||||
local count=0
|
||||
while IFS= read -r file; do
|
||||
local filename=$(basename "$file")
|
||||
local size=$(du -h "$file" | cut -f1)
|
||||
local date=$(echo "$filename" | grep -oP '\d{8}-\d{6}' || echo "未知")
|
||||
|
||||
printf " ${CYAN}•${NC} %-60s %8s\n" "$filename" "$size"
|
||||
((count++))
|
||||
done < <(find "$backup_path" -name "*.tar.gz" -type f 2>/dev/null | sort -r)
|
||||
|
||||
if [[ $count -eq 0 ]]; then
|
||||
log_warning "无可用备份"
|
||||
else
|
||||
log_info "共 $count 个备份"
|
||||
fi
|
||||
}
|
||||
|
||||
# 恢复备份
|
||||
restore_backup() {
|
||||
local backup_file="$1"
|
||||
|
||||
if [[ ! -f "$backup_file" ]]; then
|
||||
log_error "备份文件不存在: $backup_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_warning "恢复备份将覆盖现有数据"
|
||||
log_info "备份文件: $(basename "$backup_file")"
|
||||
|
||||
# 确定恢复目标
|
||||
local target_dir=""
|
||||
if [[ "$backup_file" =~ /worlds/ ]]; then
|
||||
target_dir="$DATA_DIR"
|
||||
elif [[ "$backup_file" =~ /configs/ ]]; then
|
||||
target_dir=$(dirname "$CONFIGS_DIR")
|
||||
elif [[ "$backup_file" =~ /mods/ ]]; then
|
||||
target_dir=$(dirname "$MODS_DIR")
|
||||
else
|
||||
log_error "无法确定备份类型"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "恢复目标: $target_dir"
|
||||
|
||||
# 解压备份
|
||||
if tar -xzf "$backup_file" -C "$target_dir"; then
|
||||
log_success "备份恢复完成"
|
||||
return 0
|
||||
else
|
||||
log_error "备份恢复失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 清理函数
|
||||
# ============================================
|
||||
|
||||
# 清理旧备份
|
||||
cleanup_backups() {
|
||||
local keep="${1:-5}"
|
||||
|
||||
log_info "清理旧备份(保留最近 $keep 个)..."
|
||||
log_separator
|
||||
|
||||
cleanup_old_backups "$BACKUP_DIR/worlds" "$keep"
|
||||
cleanup_old_backups "$BACKUP_DIR/configs" "$keep"
|
||||
cleanup_old_backups "$BACKUP_DIR/mods" "$keep"
|
||||
|
||||
log_success "备份清理完成"
|
||||
}
|
||||
|
||||
# 显示备份统计
|
||||
show_backup_stats() {
|
||||
log_info "备份统计信息"
|
||||
log_separator
|
||||
|
||||
local types=("worlds:世界数据" "configs:配置文件" "mods:Mods")
|
||||
|
||||
for type_pair in "${types[@]}"; do
|
||||
local type="${type_pair%%:*}"
|
||||
local name="${type_pair##*:}"
|
||||
local backup_path="$BACKUP_DIR/$type"
|
||||
|
||||
if [[ -d "$backup_path" ]]; then
|
||||
local count=$(find "$backup_path" -name "*.tar.gz" 2>/dev/null | wc -l)
|
||||
local total_size=$(du -sh "$backup_path" 2>/dev/null | cut -f1)
|
||||
|
||||
log_info "$name: $count 个备份, 总大小: $total_size"
|
||||
else
|
||||
log_info "$name: 无备份"
|
||||
fi
|
||||
done
|
||||
|
||||
log_separator
|
||||
|
||||
if [[ -d "$BACKUP_DIR" ]]; then
|
||||
local total_size=$(du -sh "$BACKUP_DIR" 2>/dev/null | cut -f1)
|
||||
log_info "备份总大小: $total_size"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 主函数
|
||||
# ============================================
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF
|
||||
Minecraft 服务器备份管理
|
||||
|
||||
用法: $(basename "$0") [命令] [选项]
|
||||
|
||||
命令:
|
||||
backup [type] 创建备份
|
||||
type:
|
||||
world 仅备份世界数据
|
||||
config 仅备份配置文件
|
||||
mods 仅备份 mods
|
||||
all 完整备份(默认)
|
||||
|
||||
list [type] 列出可用备份
|
||||
restore <file> 恢复指定备份
|
||||
cleanup [num] 清理旧备份(默认保留5个)
|
||||
stats 显示备份统计信息
|
||||
help 显示此帮助信息
|
||||
|
||||
示例:
|
||||
$(basename "$0") backup all # 完整备份
|
||||
$(basename "$0") backup world # 仅备份世界
|
||||
$(basename "$0") list # 列出所有备份
|
||||
$(basename "$0") cleanup 10 # 保留最近10个备份
|
||||
|
||||
备份位置: $BACKUP_DIR
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
local command="${1:-help}"
|
||||
shift || true
|
||||
|
||||
# 初始化日志
|
||||
init_log "Minecraft 备份管理"
|
||||
log_system_info
|
||||
|
||||
case "$command" in
|
||||
backup)
|
||||
local type="${1:-all}"
|
||||
case "$type" in
|
||||
world | worlds)
|
||||
backup_world
|
||||
;;
|
||||
config | configs)
|
||||
backup_configs
|
||||
;;
|
||||
mods)
|
||||
backup_mods
|
||||
;;
|
||||
all | *)
|
||||
backup_all
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
list)
|
||||
list_backups "${1:-all}"
|
||||
;;
|
||||
|
||||
restore)
|
||||
local file="$1"
|
||||
if [[ -z "$file" ]]; then
|
||||
log_error "请指定备份文件"
|
||||
exit 1
|
||||
fi
|
||||
restore_backup "$file"
|
||||
;;
|
||||
|
||||
cleanup)
|
||||
cleanup_backups "${1:-5}"
|
||||
;;
|
||||
|
||||
stats)
|
||||
show_backup_stats
|
||||
;;
|
||||
|
||||
help | --help | -h)
|
||||
show_usage
|
||||
;;
|
||||
|
||||
*)
|
||||
log_error "未知命令: $command"
|
||||
echo ""
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
show_log_file
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
344
minecraft/scripts/mod-manager.sh
Executable file
344
minecraft/scripts/mod-manager.sh
Executable file
|
|
@ -0,0 +1,344 @@
|
|||
#!/usr/bin/env bash
|
||||
# Minecraft Mods 管理器
|
||||
# 支持从 Modrinth 下载、更新、清理 mods
|
||||
|
||||
set -e
|
||||
|
||||
# 加载工具库
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/utils.sh"
|
||||
|
||||
# ============================================
|
||||
# 配置变量
|
||||
# ============================================
|
||||
readonly PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
readonly MODS_DIR="$PROJECT_ROOT/mods"
|
||||
readonly MODS_LIST="$PROJECT_ROOT/extras/mods.txt"
|
||||
readonly MC_VERSION="1.21.1"
|
||||
readonly LOADER="fabric"
|
||||
readonly MODRINTH_API="https://api.modrinth.com/v2"
|
||||
|
||||
# ============================================
|
||||
# Modrinth API 函数
|
||||
# ============================================
|
||||
|
||||
# 获取项目信息
|
||||
get_project_info() {
|
||||
local slug="$1"
|
||||
local response
|
||||
|
||||
response=$(curl -s "$MODRINTH_API/project/$slug")
|
||||
|
||||
if [[ $? -ne 0 || -z "$response" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$response"
|
||||
}
|
||||
|
||||
# 获取最新版本
|
||||
get_latest_version() {
|
||||
local slug="$1"
|
||||
local game_version="$2"
|
||||
local loader="$3"
|
||||
|
||||
local url="$MODRINTH_API/project/$slug/version"
|
||||
url+="?game_versions=%5B%22${game_version}%22%5D"
|
||||
url+="&loaders=%5B%22${loader}%22%5D"
|
||||
|
||||
local response=$(curl -s "$url")
|
||||
|
||||
if [[ $? -ne 0 || -z "$response" || "$response" == "[]" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$response"
|
||||
}
|
||||
|
||||
# 解析下载信息
|
||||
parse_download_info() {
|
||||
local json="$1"
|
||||
|
||||
# 提取文件名和下载链接
|
||||
local filename=$(echo "$json" | grep -o '"filename":"[^"]*"' | head -1 | cut -d'"' -f4)
|
||||
local url=$(echo "$json" | grep -o '"url":"[^"]*"' | head -1 | cut -d'"' -f4)
|
||||
|
||||
if [[ -z "$filename" || -z "$url" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$filename|$url"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Mods 下载函数
|
||||
# ============================================
|
||||
|
||||
# 下载单个 mod
|
||||
download_mod() {
|
||||
local slug="$1"
|
||||
local mod_name="${2:-$slug}"
|
||||
|
||||
log_info "处理: $mod_name ($slug)"
|
||||
|
||||
# 获取版本信息
|
||||
local versions=$(get_latest_version "$slug" "$MC_VERSION" "$LOADER")
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
log_error "未找到适配版本: $slug"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 解析下载信息
|
||||
local download_info=$(parse_download_info "$versions")
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
log_error "解析下载信息失败: $slug"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local filename=$(echo "$download_info" | cut -d'|' -f1)
|
||||
local download_url=$(echo "$download_info" | cut -d'|' -f2)
|
||||
|
||||
# 检查文件是否已存在
|
||||
if [[ -f "$MODS_DIR/$filename" ]]; then
|
||||
log_info "已存在: $filename"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 下载文件
|
||||
log_info "下载: $filename"
|
||||
|
||||
if curl -L -o "$MODS_DIR/$filename" "$download_url" 2>/dev/null; then
|
||||
# 验证文件大小
|
||||
local size=$(stat -f%z "$MODS_DIR/$filename" 2>/dev/null || stat -c%s "$MODS_DIR/$filename" 2>/dev/null)
|
||||
|
||||
if [[ $size -gt 1000 ]]; then
|
||||
log_success "下载完成: $filename ($(($size / 1024)) KB)"
|
||||
return 0
|
||||
else
|
||||
log_error "文件大小异常: $filename ($size bytes)"
|
||||
rm -f "$MODS_DIR/$filename"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "下载失败: $slug"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 从列表下载所有 mods
|
||||
download_all_mods() {
|
||||
if [[ ! -f "$MODS_LIST" ]]; then
|
||||
log_error "Mods 列表不存在: $MODS_LIST"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "开始批量下载 mods"
|
||||
log_info "Minecraft 版本: $MC_VERSION"
|
||||
log_info "加载器: $LOADER"
|
||||
log_info "目标目录: $MODS_DIR"
|
||||
|
||||
mkdir -p "$MODS_DIR"
|
||||
|
||||
local success_count=0
|
||||
local fail_count=0
|
||||
local skip_count=0
|
||||
|
||||
while IFS= read -r line; do
|
||||
# 跳过空行和注释
|
||||
line=$(echo "$line" | xargs)
|
||||
if [[ -z "$line" || "$line" =~ ^# ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
log_separator
|
||||
|
||||
if download_mod "$line"; then
|
||||
((success_count++))
|
||||
else
|
||||
((fail_count++))
|
||||
fi
|
||||
|
||||
# 限流,避免API限制
|
||||
sleep 1
|
||||
|
||||
done <"$MODS_LIST"
|
||||
|
||||
log_separator
|
||||
log_info "下载完成 - 成功: $success_count, 失败: $fail_count"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Mods 管理函数
|
||||
# ============================================
|
||||
|
||||
# 列出已安装的 mods
|
||||
list_mods() {
|
||||
log_info "已安装的 Mods:"
|
||||
|
||||
if [[ ! -d "$MODS_DIR" || -z "$(ls -A "$MODS_DIR" 2>/dev/null)" ]]; then
|
||||
log_warning "未找到任何 mods"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local count=0
|
||||
while IFS= read -r file; do
|
||||
local filename=$(basename "$file")
|
||||
local size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
|
||||
local size_kb=$(($size / 1024))
|
||||
|
||||
printf " ${GREEN}•${NC} %-50s %8s KB\n" "$filename" "$size_kb"
|
||||
((count++))
|
||||
done < <(find "$MODS_DIR" -name "*.jar" -type f 2>/dev/null | sort)
|
||||
|
||||
log_info "总计: $count 个 mods"
|
||||
}
|
||||
|
||||
# 清理 mods
|
||||
clean_mods() {
|
||||
local backup="${1:-true}"
|
||||
|
||||
if [[ ! -d "$MODS_DIR" ]]; then
|
||||
log_info "Mods 目录不存在,无需清理"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local count=$(find "$MODS_DIR" -name "*.jar" 2>/dev/null | wc -l)
|
||||
|
||||
if [[ $count -eq 0 ]]; then
|
||||
log_info "没有 mods 需要清理"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_warning "准备清理 $count 个 mods"
|
||||
|
||||
# 创建备份
|
||||
if [[ "$backup" == "true" ]]; then
|
||||
create_backup "$MODS_DIR"
|
||||
fi
|
||||
|
||||
# 删除所有 jar 文件
|
||||
find "$MODS_DIR" -name "*.jar" -type f -delete
|
||||
|
||||
log_success "Mods 清理完成"
|
||||
}
|
||||
|
||||
# 更新所有 mods
|
||||
update_mods() {
|
||||
log_info "更新所有 mods"
|
||||
|
||||
# 备份并清理现有 mods
|
||||
clean_mods true
|
||||
|
||||
# 重新下载
|
||||
download_all_mods
|
||||
}
|
||||
|
||||
# 检查 mods 状态
|
||||
check_mods() {
|
||||
log_info "检查 Mods 状态"
|
||||
|
||||
if [[ ! -d "$MODS_DIR" ]]; then
|
||||
log_warning "Mods 目录不存在"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local jar_count=$(find "$MODS_DIR" -name "*.jar" 2>/dev/null | wc -l)
|
||||
local total_size=$(du -sh "$MODS_DIR" 2>/dev/null | cut -f1)
|
||||
|
||||
log_info "Mods 数量: $jar_count"
|
||||
log_info "总大小: $total_size"
|
||||
|
||||
# 检查必需的核心 mods
|
||||
local required_mods=("fabric-api")
|
||||
local missing_count=0
|
||||
|
||||
for mod in "${required_mods[@]}"; do
|
||||
if ! find "$MODS_DIR" -name "*${mod}*.jar" | grep -q .; then
|
||||
log_warning "缺少核心 mod: $mod"
|
||||
((missing_count++))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $missing_count -gt 0 ]]; then
|
||||
log_warning "缺少 $missing_count 个核心 mods,建议运行下载命令"
|
||||
else
|
||||
log_success "核心 mods 完整"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 主函数
|
||||
# ============================================
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF
|
||||
Minecraft Mods 管理器
|
||||
|
||||
用法: $(basename "$0") [命令]
|
||||
|
||||
命令:
|
||||
download 下载所有 mods(根据 extras/mods.txt)
|
||||
list 列出已安装的 mods
|
||||
update 更新所有 mods(备份、清理、重新下载)
|
||||
clean 清理所有 mods(自动备份)
|
||||
check 检查 mods 状态
|
||||
help 显示此帮助信息
|
||||
|
||||
示例:
|
||||
$(basename "$0") download # 下载所有 mods
|
||||
$(basename "$0") list # 列出已安装的 mods
|
||||
$(basename "$0") update # 更新所有 mods
|
||||
|
||||
配置文件:
|
||||
Mods 列表: $MODS_LIST
|
||||
Mods 目录: $MODS_DIR
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
local command="${1:-help}"
|
||||
|
||||
# 初始化日志
|
||||
init_log "Minecraft Mods 管理器"
|
||||
log_system_info
|
||||
|
||||
case "$command" in
|
||||
download)
|
||||
check_network || exit 1
|
||||
download_all_mods
|
||||
;;
|
||||
list)
|
||||
list_mods
|
||||
;;
|
||||
update)
|
||||
check_network || exit 1
|
||||
update_mods
|
||||
;;
|
||||
clean)
|
||||
clean_mods true
|
||||
;;
|
||||
check)
|
||||
check_mods
|
||||
;;
|
||||
help | --help | -h)
|
||||
show_usage
|
||||
;;
|
||||
*)
|
||||
log_error "未知命令: $command"
|
||||
echo ""
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
show_log_file
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
315
minecraft/scripts/monitor.sh
Executable file
315
minecraft/scripts/monitor.sh
Executable file
|
|
@ -0,0 +1,315 @@
|
|||
#!/usr/bin/env bash
|
||||
# Minecraft 服务器监控脚本
|
||||
# 监控容器状态、资源使用、玩家在线等信息
|
||||
|
||||
set -e
|
||||
|
||||
# 加载工具库
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/utils.sh"
|
||||
|
||||
# ============================================
|
||||
# 配置变量
|
||||
# ============================================
|
||||
readonly PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
readonly CONTAINER_NAME="mc-fabric-1.21.1"
|
||||
|
||||
# ============================================
|
||||
# 容器状态检查
|
||||
# ============================================
|
||||
|
||||
check_container() {
|
||||
log_info "检查容器状态..."
|
||||
|
||||
local status=$(check_container_status "$CONTAINER_NAME")
|
||||
|
||||
case "$status" in
|
||||
running)
|
||||
log_success "容器正在运行"
|
||||
return 0
|
||||
;;
|
||||
stopped)
|
||||
log_warning "容器已停止"
|
||||
return 1
|
||||
;;
|
||||
not_found)
|
||||
log_error "容器不存在"
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 资源使用监控
|
||||
# ============================================
|
||||
|
||||
show_resource_usage() {
|
||||
log_info "资源使用情况"
|
||||
log_separator
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log_warning "容器未运行"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 获取容器统计信息
|
||||
local stats=$(docker stats --no-stream --format "{{.CPUPerc}}|{{.MemUsage}}|{{.NetIO}}|{{.BlockIO}}" "$CONTAINER_NAME")
|
||||
|
||||
local cpu=$(echo "$stats" | cut -d'|' -f1)
|
||||
local mem=$(echo "$stats" | cut -d'|' -f2)
|
||||
local net=$(echo "$stats" | cut -d'|' -f3)
|
||||
local disk=$(echo "$stats" | cut -d'|' -f4)
|
||||
|
||||
printf "${CYAN}CPU 使用:${NC} %s\n" "$cpu"
|
||||
printf "${CYAN}内存使用:${NC} %s\n" "$mem"
|
||||
printf "${CYAN}网络 I/O:${NC} %s\n" "$net"
|
||||
printf "${CYAN}磁盘 I/O:${NC} %s\n" "$disk"
|
||||
|
||||
log_separator
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 服务器信息
|
||||
# ============================================
|
||||
|
||||
show_server_info() {
|
||||
log_info "服务器信息"
|
||||
log_separator
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log_warning "容器未运行"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 容器运行时间
|
||||
local uptime=$(docker inspect --format='{{.State.StartedAt}}' "$CONTAINER_NAME")
|
||||
uptime=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${uptime:0:19}" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$uptime")
|
||||
|
||||
printf "${CYAN}启动时间:${NC} %s\n" "$uptime"
|
||||
|
||||
# 端口映射
|
||||
local ports=$(docker port "$CONTAINER_NAME" 2>/dev/null | grep "25565" | head -1)
|
||||
printf "${CYAN}服务端口:${NC} %s\n" "${ports:-未映射}"
|
||||
|
||||
# 容器 IP
|
||||
local container_ip=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$CONTAINER_NAME")
|
||||
printf "${CYAN}容器 IP:${NC} %s\n" "${container_ip:-未知}"
|
||||
|
||||
log_separator
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 玩家信息
|
||||
# ============================================
|
||||
|
||||
show_players() {
|
||||
log_info "在线玩家"
|
||||
log_separator
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log_warning "容器未运行"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 尝试使用 rcon 获取玩家列表
|
||||
local player_list=$(docker exec "$CONTAINER_NAME" rcon-cli list 2>/dev/null || echo "无法获取玩家信息")
|
||||
|
||||
if [[ "$player_list" =~ "There are" ]]; then
|
||||
echo "$player_list"
|
||||
else
|
||||
log_warning "无法获取玩家信息(可能需要配置 RCON)"
|
||||
fi
|
||||
|
||||
log_separator
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 日志监控
|
||||
# ============================================
|
||||
|
||||
show_recent_logs() {
|
||||
local lines="${1:-20}"
|
||||
|
||||
log_info "最近 $lines 行日志"
|
||||
log_separator
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log_warning "容器未运行"
|
||||
return 1
|
||||
fi
|
||||
|
||||
docker logs --tail "$lines" "$CONTAINER_NAME" 2>&1
|
||||
|
||||
log_separator
|
||||
}
|
||||
|
||||
# 监控日志中的错误
|
||||
check_errors() {
|
||||
log_info "检查错误日志"
|
||||
log_separator
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log_warning "容器未运行"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local error_count=$(docker logs --tail 1000 "$CONTAINER_NAME" 2>&1 | grep -ic "error" || echo "0")
|
||||
local warn_count=$(docker logs --tail 1000 "$CONTAINER_NAME" 2>&1 | grep -ic "warn" || echo "0")
|
||||
|
||||
if [[ $error_count -gt 0 ]]; then
|
||||
log_warning "发现 $error_count 个错误"
|
||||
else
|
||||
log_success "无错误日志"
|
||||
fi
|
||||
|
||||
if [[ $warn_count -gt 0 ]]; then
|
||||
log_warning "发现 $warn_count 个警告"
|
||||
fi
|
||||
|
||||
log_separator
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 完整状态报告
|
||||
# ============================================
|
||||
|
||||
show_full_status() {
|
||||
log_info "=== Minecraft 服务器完整状态 ==="
|
||||
log_separator
|
||||
|
||||
# 检查容器
|
||||
if ! check_container; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_separator
|
||||
|
||||
# 服务器信息
|
||||
show_server_info
|
||||
|
||||
# 资源使用
|
||||
show_resource_usage
|
||||
|
||||
# 玩家信息
|
||||
show_players
|
||||
|
||||
# 错误检查
|
||||
check_errors
|
||||
|
||||
log_success "状态检查完成"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 持续监控
|
||||
# ============================================
|
||||
|
||||
watch_mode() {
|
||||
local interval="${1:-5}"
|
||||
|
||||
log_info "开始持续监控(每 ${interval}s 刷新,Ctrl+C 退出)"
|
||||
log_separator
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo "=== Minecraft 服务器监控 ==="
|
||||
echo "刷新时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo ""
|
||||
|
||||
show_server_info 2>/dev/null || true
|
||||
show_resource_usage 2>/dev/null || true
|
||||
show_players 2>/dev/null || true
|
||||
|
||||
sleep "$interval"
|
||||
done
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 主函数
|
||||
# ============================================
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF
|
||||
Minecraft 服务器监控工具
|
||||
|
||||
用法: $(basename "$0") [命令] [选项]
|
||||
|
||||
命令:
|
||||
status 显示完整状态(默认)
|
||||
container 检查容器状态
|
||||
resources 显示资源使用情况
|
||||
server 显示服务器信息
|
||||
players 显示在线玩家
|
||||
logs [n] 显示最近 n 行日志(默认20行)
|
||||
errors 检查错误日志
|
||||
watch [sec] 持续监控模式(默认每5秒刷新)
|
||||
help 显示此帮助信息
|
||||
|
||||
示例:
|
||||
$(basename "$0") # 显示完整状态
|
||||
$(basename "$0") resources # 仅显示资源使用
|
||||
$(basename "$0") logs 50 # 显示最近50行日志
|
||||
$(basename "$0") watch 10 # 每10秒刷新一次
|
||||
|
||||
容器名称: $CONTAINER_NAME
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
local command="${1:-status}"
|
||||
shift || true
|
||||
|
||||
# 初始化日志
|
||||
init_log "Minecraft 服务器监控"
|
||||
|
||||
case "$command" in
|
||||
status)
|
||||
show_full_status
|
||||
;;
|
||||
|
||||
container)
|
||||
check_container
|
||||
;;
|
||||
|
||||
resources | res)
|
||||
show_resource_usage
|
||||
;;
|
||||
|
||||
server | info)
|
||||
show_server_info
|
||||
;;
|
||||
|
||||
players | player)
|
||||
show_players
|
||||
;;
|
||||
|
||||
logs | log)
|
||||
show_recent_logs "${1:-20}"
|
||||
;;
|
||||
|
||||
errors | error)
|
||||
check_errors
|
||||
;;
|
||||
|
||||
watch)
|
||||
watch_mode "${1:-5}"
|
||||
;;
|
||||
|
||||
help | --help | -h)
|
||||
show_usage
|
||||
;;
|
||||
|
||||
*)
|
||||
log_error "未知命令: $command"
|
||||
echo ""
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$command" != "watch" ]]; then
|
||||
show_log_file
|
||||
fi
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
184
minecraft/scripts/setup.sh
Executable file
184
minecraft/scripts/setup.sh
Executable file
|
|
@ -0,0 +1,184 @@
|
|||
#!/usr/bin/env bash
|
||||
# Minecraft 服务器初始化脚本
|
||||
# 用于首次部署或环境重置
|
||||
|
||||
set -e
|
||||
|
||||
# 加载工具库
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/utils.sh"
|
||||
|
||||
# ============================================
|
||||
# 配置变量
|
||||
# ============================================
|
||||
readonly PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# ============================================
|
||||
# 初始化检查
|
||||
# ============================================
|
||||
|
||||
check_prerequisites() {
|
||||
log_info "检查系统环境..."
|
||||
|
||||
# 检查 Docker
|
||||
if ! check_docker; then
|
||||
log_error "Docker 环境检查失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查必需文件
|
||||
local required_files=(
|
||||
"$PROJECT_ROOT/docker-compose.yml"
|
||||
"$PROJECT_ROOT/.env"
|
||||
)
|
||||
|
||||
for file in "${required_files[@]}"; do
|
||||
if ! check_file "$file"; then
|
||||
log_error "缺少必需文件"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
log_success "环境检查通过"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 目录结构初始化
|
||||
# ============================================
|
||||
|
||||
init_directories() {
|
||||
log_info "初始化目录结构..."
|
||||
|
||||
local dirs=(
|
||||
"$PROJECT_ROOT/data"
|
||||
"$PROJECT_ROOT/mods"
|
||||
"$PROJECT_ROOT/configs"
|
||||
"$PROJECT_ROOT/backups"
|
||||
"$PROJECT_ROOT/logs"
|
||||
)
|
||||
|
||||
for dir in "${dirs[@]}"; do
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
mkdir -p "$dir"
|
||||
log_success "创建目录: $(basename "$dir")"
|
||||
else
|
||||
log_info "目录已存在: $(basename "$dir")"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 配置文件初始化
|
||||
# ============================================
|
||||
|
||||
check_env_config() {
|
||||
log_info "检查环境配置..."
|
||||
|
||||
local env_file="$PROJECT_ROOT/.env"
|
||||
|
||||
# 检查关键配置
|
||||
if grep -q "your_rcon_password_here" "$env_file"; then
|
||||
log_warning ".env 中的 RCON_PASSWORD 未配置"
|
||||
log_warning "请编辑 .env 文件并设置安全的密码"
|
||||
fi
|
||||
|
||||
# 检查 UID/GID
|
||||
local current_uid=$(id -u)
|
||||
local current_gid=$(id -g)
|
||||
|
||||
if ! grep -q "UID=$current_uid" "$env_file"; then
|
||||
log_info "当前用户 UID: $current_uid"
|
||||
log_warning "建议更新 .env 中的 UID 为: $current_uid"
|
||||
fi
|
||||
|
||||
if ! grep -q "GID=$current_gid" "$env_file"; then
|
||||
log_info "当前用户 GID: $current_gid"
|
||||
log_warning "建议更新 .env 中的 GID 为: $current_gid"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Mods 初始化
|
||||
# ============================================
|
||||
|
||||
init_mods() {
|
||||
log_info "检查 Mods 状态..."
|
||||
|
||||
local mods_count=$(find "$PROJECT_ROOT/mods" -name "*.jar" 2>/dev/null | wc -l)
|
||||
|
||||
if [[ $mods_count -eq 0 ]]; then
|
||||
log_warning "未找到任何 mods"
|
||||
log_info "建议运行: make minecraft-mods-download"
|
||||
else
|
||||
log_success "发现 $mods_count 个 mods"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 权限设置
|
||||
# ============================================
|
||||
|
||||
fix_permissions() {
|
||||
log_info "修复文件权限..."
|
||||
|
||||
# 确保脚本可执行
|
||||
find "$PROJECT_ROOT/scripts" -name "*.sh" -type f -exec chmod +x {} \;
|
||||
|
||||
# 确保数据目录可写
|
||||
if [[ -d "$PROJECT_ROOT/data" ]]; then
|
||||
chmod -R 755 "$PROJECT_ROOT/data"
|
||||
fi
|
||||
|
||||
log_success "权限修复完成"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 显示配置摘要
|
||||
# ============================================
|
||||
|
||||
show_summary() {
|
||||
log_separator
|
||||
log_success "初始化完成!"
|
||||
echo ""
|
||||
|
||||
log_info "配置摘要:"
|
||||
log_info " 项目目录: $PROJECT_ROOT"
|
||||
log_info " Docker Compose: $(get_docker_compose_cmd)"
|
||||
log_info " Mods 数量: $(find "$PROJECT_ROOT/mods" -name "*.jar" 2>/dev/null | wc -l)"
|
||||
|
||||
echo ""
|
||||
log_info "后续步骤:"
|
||||
log_info " 1. 检查并编辑 .env 文件,设置 RCON_PASSWORD"
|
||||
log_info " 2. 如需下载 mods: make minecraft-mods-download"
|
||||
log_info " 3. 启动服务器: make minecraft-up"
|
||||
log_info " 4. 查看日志: make minecraft-logs"
|
||||
|
||||
echo ""
|
||||
show_log_file
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 主函数
|
||||
# ============================================
|
||||
|
||||
main() {
|
||||
# 初始化日志
|
||||
init_log "Minecraft 服务器初始化"
|
||||
log_system_info
|
||||
|
||||
log_info "开始初始化 Minecraft 服务器环境..."
|
||||
log_separator
|
||||
|
||||
# 执行初始化步骤
|
||||
check_prerequisites
|
||||
init_directories
|
||||
check_env_config
|
||||
init_mods
|
||||
fix_permissions
|
||||
|
||||
# 显示摘要
|
||||
show_summary
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
339
minecraft/scripts/utils.sh
Executable file
339
minecraft/scripts/utils.sh
Executable file
|
|
@ -0,0 +1,339 @@
|
|||
#!/usr/bin/env bash
|
||||
# Minecraft 自动化工具 - 通用工具库
|
||||
# 提供日志、环境检查、Docker操作等通用函数
|
||||
|
||||
# ============================================
|
||||
# 颜色定义
|
||||
# ============================================
|
||||
readonly RED='\033[0;31m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly CYAN='\033[0;36m'
|
||||
readonly NC='\033[0m' # No Color
|
||||
|
||||
# ============================================
|
||||
# 全局变量
|
||||
# ============================================
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
LOG_DIR="$PROJECT_ROOT/logs"
|
||||
LOG_FILE="$LOG_DIR/automation-$(date +%Y%m%d).log"
|
||||
|
||||
# 确保日志目录存在
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# ============================================
|
||||
# 日志函数
|
||||
# ============================================
|
||||
|
||||
# 初始化日志文件
|
||||
init_log() {
|
||||
local title="${1:-Minecraft 自动化任务}"
|
||||
{
|
||||
echo "=========================================="
|
||||
echo "$title"
|
||||
echo "开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "工作目录: $(pwd)"
|
||||
echo "用户: $(whoami)"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
} >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# 记录信息
|
||||
log_info() {
|
||||
local msg="$1"
|
||||
local timestamp=$(date '+%H:%M:%S')
|
||||
echo -e "${BLUE}[INFO]${NC} ${timestamp} $msg"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $msg" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# 记录成功
|
||||
log_success() {
|
||||
local msg="$1"
|
||||
local timestamp=$(date '+%H:%M:%S')
|
||||
echo -e "${GREEN}[✓]${NC} ${timestamp} $msg"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $msg" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# 记录警告
|
||||
log_warning() {
|
||||
local msg="$1"
|
||||
local timestamp=$(date '+%H:%M:%S')
|
||||
echo -e "${YELLOW}[⚠]${NC} ${timestamp} $msg"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] $msg" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# 记录错误
|
||||
log_error() {
|
||||
local msg="$1"
|
||||
local timestamp=$(date '+%H:%M:%S')
|
||||
echo -e "${RED}[✗]${NC} ${timestamp} $msg"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $msg" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# 记录命令执行
|
||||
log_command() {
|
||||
local cmd="$1"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [COMMAND] $cmd" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# 记录分隔线
|
||||
log_separator() {
|
||||
echo "" | tee -a "$LOG_FILE"
|
||||
echo "==========================================">>"$LOG_FILE"
|
||||
echo "" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# 显示日志位置
|
||||
show_log_file() {
|
||||
log_info "详细日志: $LOG_FILE"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 环境检查函数
|
||||
# ============================================
|
||||
|
||||
# 检查命令是否存在
|
||||
check_command() {
|
||||
local cmd="$1"
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
log_error "未找到命令: $cmd"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# 检查Docker环境
|
||||
check_docker() {
|
||||
log_info "检查 Docker 环境..."
|
||||
|
||||
if ! check_command docker; then
|
||||
log_error "Docker 未安装。请访问: https://docs.docker.com/get-docker/"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! docker info &>/dev/null; then
|
||||
log_error "Docker 服务未运行"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! command -v docker compose &>/dev/null && ! command -v docker-compose &>/dev/null; then
|
||||
log_error "Docker Compose 未安装"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_success "Docker 环境正常"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 检查文件是否存在
|
||||
check_file() {
|
||||
local file="$1"
|
||||
local desc="${2:-文件}"
|
||||
|
||||
if [[ ! -f "$file" ]]; then
|
||||
log_error "$desc 不存在: $file"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# 检查目录是否存在
|
||||
check_dir() {
|
||||
local dir="$1"
|
||||
local desc="${2:-目录}"
|
||||
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
log_error "$desc 不存在: $dir"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Docker操作函数
|
||||
# ============================================
|
||||
|
||||
# 获取Docker Compose命令
|
||||
get_docker_compose_cmd() {
|
||||
if command -v docker &>/dev/null && docker compose version &>/dev/null; then
|
||||
echo "docker compose"
|
||||
elif command -v docker-compose &>/dev/null; then
|
||||
echo "docker-compose"
|
||||
else
|
||||
log_error "未找到 Docker Compose"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查容器状态
|
||||
check_container_status() {
|
||||
local container_name="${1:-mc-fabric-1.21.1}"
|
||||
|
||||
if docker ps --format '{{.Names}}' | grep -q "^${container_name}$"; then
|
||||
echo "running"
|
||||
return 0
|
||||
elif docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
|
||||
echo "stopped"
|
||||
return 1
|
||||
else
|
||||
echo "not_found"
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
# 等待容器启动
|
||||
wait_for_container() {
|
||||
local container_name="${1:-mc-fabric-1.21.1}"
|
||||
local timeout="${2:-60}"
|
||||
local elapsed=0
|
||||
|
||||
log_info "等待容器启动: $container_name"
|
||||
|
||||
while [[ $elapsed -lt $timeout ]]; do
|
||||
if docker ps --format '{{.Names}}' | grep -q "^${container_name}$"; then
|
||||
log_success "容器已启动"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
((elapsed += 2))
|
||||
echo -n "."
|
||||
done
|
||||
|
||||
echo ""
|
||||
log_error "容器启动超时"
|
||||
return 1
|
||||
}
|
||||
|
||||
# 执行Docker Compose命令
|
||||
docker_compose_exec() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
local compose_cmd=$(get_docker_compose_cmd)
|
||||
|
||||
if [[ -z "$compose_cmd" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_command "$compose_cmd $cmd $*"
|
||||
cd "$PROJECT_ROOT" && $compose_cmd $cmd "$@"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 文件操作函数
|
||||
# ============================================
|
||||
|
||||
# 创建备份
|
||||
create_backup() {
|
||||
local source="$1"
|
||||
local backup_dir="${2:-$PROJECT_ROOT/backups}"
|
||||
local name=$(basename "$source")
|
||||
local timestamp=$(date +%Y%m%d-%H%M%S)
|
||||
local backup_file="$backup_dir/${name}-${timestamp}.tar.gz"
|
||||
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
log_info "创建备份: $name"
|
||||
|
||||
if [[ -d "$source" ]]; then
|
||||
if tar -czf "$backup_file" -C "$(dirname "$source")" "$name" 2>/dev/null; then
|
||||
local size=$(du -h "$backup_file" | cut -f1)
|
||||
log_success "备份完成: $(basename "$backup_file") ($size)"
|
||||
echo "$backup_file"
|
||||
return 0
|
||||
fi
|
||||
elif [[ -f "$source" ]]; then
|
||||
if cp "$source" "$backup_file"; then
|
||||
log_success "备份完成: $(basename "$backup_file")"
|
||||
echo "$backup_file"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
log_error "备份失败: $source"
|
||||
return 1
|
||||
}
|
||||
|
||||
# 清理旧备份
|
||||
cleanup_old_backups() {
|
||||
local backup_dir="$1"
|
||||
local keep_count="${2:-5}"
|
||||
|
||||
if [[ ! -d "$backup_dir" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "清理旧备份(保留最近 $keep_count 个)"
|
||||
|
||||
local backup_count=$(find "$backup_dir" -name "*.tar.gz" | wc -l)
|
||||
|
||||
if [[ $backup_count -le $keep_count ]]; then
|
||||
log_info "当前备份数: $backup_count,无需清理"
|
||||
return 0
|
||||
fi
|
||||
|
||||
find "$backup_dir" -name "*.tar.gz" -type f -printf '%T@ %p\n' | \
|
||||
sort -rn | \
|
||||
tail -n +$((keep_count + 1)) | \
|
||||
cut -d' ' -f2- | \
|
||||
while read -r file; do
|
||||
rm -f "$file"
|
||||
log_info "删除旧备份: $(basename "$file")"
|
||||
done
|
||||
|
||||
log_success "备份清理完成"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 网络检查函数
|
||||
# ============================================
|
||||
|
||||
# 检查网络连接
|
||||
check_network() {
|
||||
local url="${1:-https://api.modrinth.com/v2/project/fabric-api}"
|
||||
|
||||
if curl -s --connect-timeout 5 "$url" >/dev/null; then
|
||||
return 0
|
||||
else
|
||||
log_warning "网络连接失败: $url"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 系统信息函数
|
||||
# ============================================
|
||||
|
||||
# 记录系统信息
|
||||
log_system_info() {
|
||||
{
|
||||
echo "=== 系统信息 ==="
|
||||
echo "主机: $(hostname)"
|
||||
echo "系统: $(uname -s) $(uname -r)"
|
||||
echo "架构: $(uname -m)"
|
||||
|
||||
if command -v docker &>/dev/null; then
|
||||
echo "Docker: $(docker --version 2>/dev/null || echo '未安装')"
|
||||
fi
|
||||
|
||||
if command -v free &>/dev/null; then
|
||||
echo "内存: $(free -h | grep Mem: | awk '{print $3 "/" $2}')"
|
||||
fi
|
||||
|
||||
echo "磁盘: $(df -h "$PROJECT_ROOT" | tail -1 | awk '{print $3 "/" $2 " (已用 " $5 ")"}')"
|
||||
echo "===================="
|
||||
} >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 主函数
|
||||
# ============================================
|
||||
|
||||
# 如果直接执行此脚本
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
echo "这是一个工具库,请通过 source 命令加载"
|
||||
echo "用法: source $(basename "$0")"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in a new issue