Compare commits

15 Commits
dev ... master

7 changed files with 225 additions and 57 deletions

3
.env
View File

@@ -1,4 +1,5 @@
STEAM_USERNAME=your_steam_username STEAM_USERNAME=your_steam_username
STEAM_PASSWORD=your_steam_password STEAM_PASSWORD=your_steam_password
MOD_IDS=123456789,987654321 # 默认安装CF VPPAdminTools VppMap ZH_ChatInputFix
MOD_IDS=1559212036,1828439124,1623711988,2966069604

View File

@@ -35,3 +35,6 @@ RConPort 2314
RConPassword $password RConPassword $password
RestrictRCon 0 RestrictRCon 0
EOF EOF
# 更新mod
bash /opt/updatemod.sh

View File

@@ -33,6 +33,68 @@ copy_files() {
start_dayzserver() { start_dayzserver() {
cd /root/Steam/steamapps/common/DayZServer cd /root/Steam/steamapps/common/DayZServer
# 启动服务器之前,检查mod是否有更新.
bash /opt/updatemod.sh update_server
updatemodpath="/root/Steam/steamapps/workshop/content/221100"
target_dir="/root/Steam/steamapps/common/DayZServer/client_mod"
# 1. 删除target_dir目录下的所有软链接
echo "清理现有的软链接..."
if [ -d "$target_dir" ]; then
find "$target_dir" -type l -delete
echo "已删除 $target_dir 目录下的所有软链接"
else
mkdir -p "$target_dir"
echo "创建目录: $target_dir"
fi
# 2. 根据MOD_IDS列表创建软链接
if [ -n "$MOD_IDS" ]; then
echo "开始根据MOD_IDS创建软链接..."
IFS=',' read -ra MOD_ARRAY <<< "$MOD_IDS"
for mod_id in "${MOD_ARRAY[@]}"; do
echo "处理Mod ID: $mod_id"
# 查找对应的mod目录
mod_dir=$(find "$updatemodpath" -mindepth 1 -maxdepth 1 -type d -name "$mod_id" -print -quit)
if [[ -n "$mod_dir" ]]; then
echo "找到Mod目录: $mod_dir"
# 查找meta.cpp文件获取mod名称
meta_file=$(find "$mod_dir" -type f -name "meta.cpp" -print -quit)
if [[ -f "$meta_file" ]]; then
mod_name=$(grep -oP 'name\s*=\s*"\K[^"]*' "$meta_file")
if [[ -n "$mod_name" ]]; then
symlink_path="${target_dir}/@${mod_name}"
echo "为 [$mod_name] (ID: $mod_id) 创建软链接: $symlink_path$mod_dir"
ln -s "$mod_dir" "$symlink_path"
else
echo "警告: 在 $meta_file 中未找到 name 字段使用ID作为名称"
symlink_path="${target_dir}/@${mod_id}"
echo "为 [ID: $mod_id] 创建软链接: $symlink_path$mod_dir"
ln -s "$mod_dir" "$symlink_path"
fi
else
echo "警告: 在 $mod_dir 中未找到 meta.cpp 文件使用ID作为名称"
symlink_path="${target_dir}/@${mod_id}"
echo "为 [ID: $mod_id] 创建软链接: $symlink_path$mod_dir"
ln -s "$mod_dir" "$symlink_path"
fi
else
echo "警告: 未找到ID为 $mod_id 的Mod目录"
fi
done
echo "软链接创建完成!"
else
echo "未配置MOD_IDS跳过软链接创建"
fi
# 初始化mod变量 # 初始化mod变量
client_mods="" client_mods=""
server_mods="" server_mods=""
@@ -44,7 +106,7 @@ start_dayzserver() {
client_mods="${client_mods};" client_mods="${client_mods};"
fi fi
client_mods="${client_mods}${folder}" client_mods="${client_mods}${folder}"
done < <(find "./client_mod" -type d -name '@*' -print0) done < <(find "./client_mod" -xtype d -name '@*' -print0)
while IFS= read -r -d $'\0' folder; do while IFS= read -r -d $'\0' folder; do
echo "处理服务端mod: $folder" echo "处理服务端mod: $folder"
@@ -53,7 +115,7 @@ start_dayzserver() {
server_mods="${server_mods};" server_mods="${server_mods};"
fi fi
server_mods="${server_mods}${folder}" server_mods="${server_mods}${folder}"
done < <(find "./server_mod" -type d -name '@*' -print0) done < <(find "./server_mod" -xtype d -name '@*' -print0)
# 崩溃检测和自动重启循环 # 崩溃检测和自动重启循环
while true; do while true; do
@@ -106,6 +168,8 @@ start_dayzserver() {
if [ ! -f "/opt/steamcmd/steamcmd.sh" ]; then if [ ! -f "/opt/steamcmd/steamcmd.sh" ]; then
echo "SteamCMD未安装开始下载和安装..." echo "SteamCMD未安装开始下载和安装..."
echo "下载SteamCMD..." echo "下载SteamCMD..."
unset http_proxy
unset https_proxy
wget -O /opt/steamcmd/steamcmd_linux.tar.gz ${STEAMCMD_URL} wget -O /opt/steamcmd/steamcmd_linux.tar.gz ${STEAMCMD_URL}
echo "解压SteamCMD..." echo "解压SteamCMD..."
tar xvzf /opt/steamcmd/steamcmd_linux.tar.gz -C /opt/steamcmd tar xvzf /opt/steamcmd/steamcmd_linux.tar.gz -C /opt/steamcmd
@@ -118,6 +182,7 @@ else
echo "SteamCMD已存在跳过安装" echo "SteamCMD已存在跳过安装"
fi fi
if [ ! -f "/root/Steam/steamapps/common/DayZServer/DayZServer" ]; then if [ ! -f "/root/Steam/steamapps/common/DayZServer/DayZServer" ]; then
echo "DayZServer未安装开始安装..." echo "DayZServer未安装开始安装..."
bash /opt/install_dayz.sh bash /opt/install_dayz.sh
@@ -125,7 +190,7 @@ else
echo "DayZServer已安装检查更新" echo "DayZServer已安装检查更新"
# 切换到SteamCMD目录 # 切换到SteamCMD目录
cd /opt/steamcmd cd /opt/steamcmd
./steamcmd.sh +login $STEAM_USERNAME $STEAM_PASSWORD +app_update 223350 validate +quit # ./steamcmd.sh +login $STEAM_USERNAME $STEAM_PASSWORD +app_update 223350 validate +quit
echo "启动DayZServer..." echo "启动DayZServer..."
cd /root/Steam/steamapps/common/DayZServer cd /root/Steam/steamapps/common/DayZServer
start_dayzserver start_dayzserver

View File

@@ -1,54 +1,82 @@
#!/bin/bash #!/bin/bash
# DayZ Mod更新脚本
# 使用方法: docker compose run --rm steamcmd updatemod
set -e set -e
echo "==========================================" # 加载环境变量解决cron任务无法读取环境变量的问题
echo "开始更新DayZ Mod..." if [ -f "/etc/environment" ]; then
echo "时间: $(date)" export $(cat /etc/environment | xargs)
echo "==========================================" fi
# 设置日志文件路径
LOG_FILE="/var/log/updatemod.log"
# 检查是否传入update_server参数
UPDATE_SERVER=false
if [ "$1" = "update_server" ]; then
UPDATE_SERVER=true
echo "==========================================" >> "$LOG_FILE"
echo "开始更新DayZ服务器和Mod..." >> "$LOG_FILE"
echo "时间: $(date)" >> "$LOG_FILE"
echo "==========================================" >> "$LOG_FILE"
else
echo "==========================================" >> "$LOG_FILE"
echo "开始更新DayZ Mod..." >> "$LOG_FILE"
echo "时间: $(date)" >> "$LOG_FILE"
echo "==========================================" >> "$LOG_FILE"
fi
# 检查环境变量 # 检查环境变量
if [ -z "$STEAM_USERNAME" ] || [ -z "$STEAM_PASSWORD" ]; then if [ -z "$STEAM_USERNAME" ] || [ -z "$STEAM_PASSWORD" ]; then
echo "错误: 请设置 STEAM_USERNAME 和 STEAM_PASSWORD 环境变量" echo "错误: 请设置 STEAM_USERNAME 和 STEAM_PASSWORD 环境变量" >> "$LOG_FILE"
echo "当前环境变量状态:" >> "$LOG_FILE"
echo "STEAM_USERNAME: ${STEAM_USERNAME:-未设置}" >> "$LOG_FILE"
echo "STEAM_PASSWORD: ${STEAM_PASSWORD:-未设置}" >> "$LOG_FILE"
exit 1 exit 1
fi fi
# 切换到SteamCMD目录
cd /opt/steamcmd cd /opt/steamcmd
# 检查SteamCMD是否已安装
if [ ! -f "/opt/steamcmd/steamcmd.sh" ]; then
echo "SteamCMD未安装开始下载和安装..."
wget -O /opt/steamcmd/steamcmd_linux.tar.gz ${STEAMCMD_URL}
tar xvzf /opt/steamcmd/steamcmd_linux.tar.gz -C /opt/steamcmd
rm /opt/steamcmd/steamcmd_linux.tar.gz
chmod +x /opt/steamcmd/steamcmd.sh
echo "SteamCMD安装完成"
fi
# 更新Mod如果有配置的话
if [ -n "$MOD_IDS" ]; then if [ -n "$MOD_IDS" ]; then
echo "开始更新Mod..." echo "开始更新Mod..." >> "$LOG_FILE"
IFS=',' read -ra MOD_ARRAY <<< "$MOD_IDS" IFS=',' read -ra MOD_ARRAY <<< "$MOD_IDS"
SCRIPT_FILE="/opt/steamcmd/update_mods.txt"
echo "创建SteamCMD脚本文件: $SCRIPT_FILE" >> "$LOG_FILE"
echo "login $STEAM_USERNAME $STEAM_PASSWORD" > "$SCRIPT_FILE"
# 如果需要更新服务器,先添加服务器更新指令
if [ "$UPDATE_SERVER" = true ]; then
echo "添加DayZ服务器更新指令 (ID: 223350)" >> "$LOG_FILE"
echo "app_update 223350 validate" >> "$SCRIPT_FILE"
fi
for mod_id in "${MOD_ARRAY[@]}"; do for mod_id in "${MOD_ARRAY[@]}"; do
echo "更新Mod ID: $mod_id" echo "添加Mod ID: $mod_id 到更新脚本" >> "$LOG_FILE"
./steamcmd.sh +login $STEAM_USERNAME $STEAM_PASSWORD +workshop_download_item 221100 $mod_id +quit echo "workshop_download_item 221100 $mod_id validate" >> "$SCRIPT_FILE"
done
echo "quit" >> "$SCRIPT_FILE"
echo "SteamCMD脚本内容:" >> "$LOG_FILE"
cat "$SCRIPT_FILE" >> "$LOG_FILE"
echo "开始执行SteamCMD脚本..." >> "$LOG_FILE"
./steamcmd.sh +runscript update_mods.txt
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "Mod $mod_id 更新完成" echo "所有Mod更新完成" >> "$LOG_FILE"
else else
echo "Mod $mod_id 更新失败" echo "Mod更新过程中出现错误" >> "$LOG_FILE"
fi fi
done
rm -f "$SCRIPT_FILE"
echo "清理临时脚本文件" >> "$LOG_FILE"
else else
echo "未配置Mod ID跳过Mod更新" echo "未配置Mod ID跳过Mod更新" >> "$LOG_FILE"
fi fi
echo "==========================================" echo "==========================================" >> "$LOG_FILE"
echo "Mod更新完成" echo "Mod更新完成" >> "$LOG_FILE"
echo "时间: $(date)" echo "时间: $(date)" >> "$LOG_FILE"
echo "==========================================" echo "==========================================" >> "$LOG_FILE"

View File

@@ -25,7 +25,7 @@
### 1. 克隆项目 ### 1. 克隆项目
```bash ```bash
git clone <repository-url> ./Docker_DayzServer git clone https://git.dcrclub.com/dcrclub/Linux_Docker_build_DayzServer.git ./Docker_DayzServer
cd Docker_DayzServer cd Docker_DayzServer
``` ```
@@ -88,7 +88,10 @@ docker-compose up -d
| `DAYZ_MISSIONS` | `dayzOffline.chernarusplus` | 服务器地图 | | `DAYZ_MISSIONS` | `dayzOffline.chernarusplus` | 服务器地图 |
| `DAYZ_SERVER_PORT` | `2302` | 服务器端口 | | `DAYZ_SERVER_PORT` | `2302` | 服务器端口 |
| `DAYZ_CPU_COUNT` | `4` | 使用的CPU核心数 | | `DAYZ_CPU_COUNT` | `4` | 使用的CPU核心数 |
| `MOD_IDS` | `空` | 需要更新的modid,例如:"123456789,987654321" | | `MOD_IDS` | - | Mod ID列表用逗号分隔 |
| `ENABLE_AUTO_UPDATE` | `true` | 是否启用自动更新 |
| `UPDATE_INTERVAL` | `15` | 自动更新间隔(分钟) |
### 端口映射 ### 端口映射
@@ -160,32 +163,49 @@ docker-compose up -d
## 🔧 Mod管理 ## 🔧 Mod管理
### 添加客户端Mod ### 自动Mod管理
项目现在支持自动Mod管理功能
1. **配置Mod ID**: 在环境变量中设置 `MOD_IDS`,例如:
```bash
MOD_IDS=123456789,987654321,456789123
```
2. **自动更新**: 系统会自动下载和更新指定的Mod
3. **自动软链接**: 系统会根据Mod ID自动创建软链接到 `client_mod` 目录
4. **智能命名**: 优先使用Mod的 `meta.cpp` 中的名称如果没有则使用Mod ID
### 手动Mod管理
如果您想手动管理Mod
1. 将Mod文件放入 `dayz/client_mod/` 目录 1. 将Mod文件放入 `dayz/client_mod/` 目录
2. Mod文件夹应以 `@` 开头 2. Mod文件夹应以 `@` 开头
3. 重启服务器以加载新Mod 3. 重启服务器以加载新Mod
### 添加服务端Mod ### 更新Mod
1. 将Mod文件放入 `dayz/server_mod/` 目录 #### 自动更新
2. Mod文件夹应以 `@` 开头 - **启用自动更新**: 设置 `ENABLE_AUTO_UPDATE=true`(默认启用)
3. 重启服务器以加载新Mod - **更新间隔**: 通过 `UPDATE_INTERVAL` 设置默认15分钟
- **查看更新日志**: `docker-compose exec steamcmd cat /var/log/updatemod.log`
### 更新客户端Mod #### 手动更新
1. 需要先停止容器运行 `docker compose down` 1. 需要先停止容器运行 `docker compose down`
2. 然后运行更新命令 `docker compose run --rm steamcmd updatemod` 2. 然后运行更新命令 `docker compose run --rm steamcmd updatemod`
3. 更新完毕后启动docker容器即可. 3. 更新完毕后启动docker容器即可
### Mod配置示例 ### Mod配置示例
``` ```
dayz/ dayz/
├── client_mod/ ├── client_mod/
│ ├── @CF │ ├── @CF # 自动创建的软链接
── @DayZExpansion ── @DayZExpansion # 自动创建的软链接
│ └── @CustomMod # 手动添加的Mod
└── server_mod/ └── server_mod/
└── @DayZExpansionServer └── @DayZExpansionServer # 服务端Mod
``` ```
## 📊 监控和日志 ## 📊 监控和日志
@@ -259,6 +279,14 @@ docker-compose exec steamcmd netstat -tulpn
## 📝 更新日志 ## 📝 更新日志
### v1.1.0
- 新增自动Mod管理功能
- 支持通过MOD_IDS环境变量配置Mod
- 自动下载和更新Mod
- 智能软链接创建优先使用meta.cpp中的名称
- 新增自动更新功能cron定时任务
- 优化Mod加载逻辑
### v1.0.0 ### v1.0.0
- 初始版本发布 - 初始版本发布
- 支持基本的DayZ服务器部署 - 支持基本的DayZ服务器部署

View File

@@ -18,6 +18,8 @@ services:
- DAYZ_MISSIONS=dayzOffline.chernarusplus - DAYZ_MISSIONS=dayzOffline.chernarusplus
- DAYZ_SERVER_PORT=2302 - DAYZ_SERVER_PORT=2302
- DAYZ_CPU_COUNT=4 - DAYZ_CPU_COUNT=4
- ENABLE_AUTO_UPDATE=${ENABLE_AUTO_UPDATE:-true}
- UPDATE_INTERVAL=${UPDATE_INTERVAL:-15}
ports: ports:
- "2302:2302/udp" - "2302:2302/udp"
- "2305:2305/udp" - "2305:2305/udp"

View File

@@ -58,22 +58,22 @@ update_package_manager() {
elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]] || [[ "$OS" == *"AlmaLinux"* ]]; then elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]] || [[ "$OS" == *"AlmaLinux"* ]]; then
if command -v dnf &> /dev/null; then if command -v dnf &> /dev/null; then
dnf update -y dnf update -y
dnf install -y curl wget dnf install -y curl wget jq
else else
yum update -y yum update -y
yum install -y curl wget yum install -y curl wget jq
fi fi
else else
print_message "使用通用方式安装curl和wget..." print_message "使用通用方式安装curl和wget..."
# 尝试通用方式安装 # 尝试通用方式安装
if command -v apt &> /dev/null; then if command -v apt &> /dev/null; then
apt update && apt install -y curl wget apt update && apt install -y curl wget jq
elif command -v dnf &> /dev/null; then elif command -v dnf &> /dev/null; then
dnf install -y curl wget dnf install -y curl wget jq
elif command -v yum &> /dev/null; then elif command -v yum &> /dev/null; then
yum install -y curl wget yum install -y curl wget jq
elif command -v zypper &> /dev/null; then elif command -v zypper &> /dev/null; then
zypper install -y curl wget zypper install -y curl wget jq
else else
print_warning "无法自动安装curl和wget请手动安装" print_warning "无法自动安装curl和wget请手动安装"
fi fi
@@ -141,8 +141,49 @@ install_docker_compose() {
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
} }
# 写入JSON配置文件的函数更安全
write_json_config() {
local file_path="$1"
local json_content="$2"
mkdir -p "$(dirname "$file_path")"
if command -v jq &> /dev/null; then
if echo "$json_content" | jq . > /dev/null 2>&1; then
print_message "JSON格式验证通过"
else
print_error "JSON格式无效"
return 1
fi
fi
echo "$json_content" | tee "$file_path" > /dev/null
if [ $? -eq 0 ]; then
print_message "成功写入JSON配置文件: $file_path"
else
print_error "写入JSON配置文件失败: $file_path"
return 1
fi
}
# 验证安装 # 验证安装
verify_installation() { verify_installation() {
# 修改国内的docker源
local docker_daemon_config='{
"registry-mirrors": [
"https://docker.1panel.live",
"https://docker.1ms.run",
"https://docker.m.daocloud.io",
"https://registry.cn-hangzhou.aliyuncs.com"
]
}'
write_json_config "/etc/docker/daemon.json" "$docker_daemon_config"
systemctl daemon-reload
systemctl restart docker
print_message "验证安装..." print_message "验证安装..."
if command -v docker &> /dev/null; then if command -v docker &> /dev/null; then