-
Notifications
You must be signed in to change notification settings - Fork 0
/
entrypoint.sh
144 lines (123 loc) · 4.39 KB
/
entrypoint.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env bash
APP_ID=343050
UGC_PATH="/ugc"
MODS_PATH="/mods"
INSTALL_PATH="/install"
CLUSTER_PATH="/cluster"
STEAMCMD="/steamcmd/steamcmd.sh"
function fail() {
echo Error: "$@" >&2
exit 1
}
function check_for_file() {
if [[ ! -f "$1" ]]; then
fail "Missing file: $1"
fi
}
# 信号处理,优雅关闭服务器
trap handle_term TERM
function handle_term() {
killall -ws TERM 'steamcmd' 'dontstarve_dedicated_server_nullrenderer_x64'
exit 0
}
# 用软链接保证容器间 mods 文件夹隔离
if [[ ! -L "$INSTALL_PATH/mods" ]]; then
rm -rf "$INSTALL_PATH/mods"
ln -s "$MODS_PATH" "$INSTALL_PATH/mods"
fi
# 更新 steam 及服务端
if [[ ! -f "$INSTALL_PATH/noupdate" ]]; then
# Steam 会对安装路径的上层做权限判定,需要可写
upper_install_path=$(dirname "$INSTALL_PATH")
if [[ ! -w "$upper_install_path" ]]; then
chmod u+w "$upper_install_path"
fi
if [[ -f "$INSTALL_PATH/beta" ]]; then
BETA_ARGS="-beta updatebeta"
fi
"$STEAMCMD" \
+login anonymous \
+force_install_dir "$INSTALL_PATH" \
+app_update "$APP_ID" "$BETA_ARGS" \
+quit
fi
# 进入服务端目录
cd "$INSTALL_PATH/bin64" || fail "can't cd to $INSTALL_PATH/bin64"
# 检测分片文件夹名
mapfile -t shards < <(find "$CLUSTER_PATH" -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
# 检查分片必需配置文件
mod_ids=()
for shard in "${shards[@]}"; do
shard_path="$CLUSTER_PATH/$shard"
check_for_file "$shard_path/server.ini"
mapfile -t -O "${#mod_ids[@]}" mod_ids < <(grep -Eo "workshop-[[:digit:]]+" "$shard_path/modoverrides.lua" | sed "s/workshop-//")
done
# 更新 mod
# 使用临时分片文件夹,无需配置文件
# 避免服务端启动默认创建 Master 分片文件夹
sorted_ids=()
mapfile -t sorted_ids < <(echo "${mod_ids[@]}" | tr ' ' '\n' | sort -nu)
touch /tmp/modsettings.lua /tmp/dedicated_server_mods_setup.lua
truncate -s0 /tmp/dedicated_server_mods_setup.lua
ln -sf "/tmp/modsettings.lua" "$INSTALL_PATH/mods/modsettings.lua"
ln -sf "/tmp/dedicated_server_mods_setup.lua" "$INSTALL_PATH/mods/dedicated_server_mods_setup.lua"
for id in "${sorted_ids[@]}"; do
echo "ServerModSetup(\"$id\")" >>"/tmp/dedicated_server_mods_setup.lua"
done
if [[ -f "$INSTALL_PATH/proxy" ]]; then
export HTTP_PROXY="socks5://127.0.0.1:1080"
export HTTPS_PROXY="socks5://127.0.0.1:1080"
fi
mkdir -p '/tmp/conf/c/s'
port=$((30000 + RANDOM))
./dontstarve_dedicated_server_nullrenderer_x64 \
-only_update_server_mods \
-monitor_parent_process $$ \
-port "$port" \
-steam_master_server_port "$((port + 1))" \
-steam_authentication_port "$((port + 2))" \
-ugc_directory "$UGC_PATH" \
-persistent_storage_root '/tmp' \
-conf_dir 'conf' \
-cluster 'c' \
-shard 's' | sed -u 's/^/[MOD_UPDATE]: /'
rm -rf '/tmp/conf'
unset HTTP_PROXY HTTPS_PROXY
# 检查集群必需配置文件
check_for_file "$CLUSTER_PATH/cluster.ini"
check_for_file "$CLUSTER_PATH/cluster_token.txt"
# 确保专服特有文件夹及文件存在
touch "$CLUSTER_PATH/adminlist.txt"
touch "$CLUSTER_PATH/whitelist.txt"
touch "$CLUSTER_PATH/blocklist.txt"
# 启动集群
for shard in "${shards[@]}"; do
shard_path="$CLUSTER_PATH/$shard"
check_for_file "$shard_path/server.ini"
# 主分片的 console 作为集群 console
if grep -qiE 'is_master[[:space:]]*=[[:space:]]*true' "$shard_path/server.ini"; then
console_path="$CLUSTER_PATH/console"
else
console_path="$shard_path/console"
fi
# 创建命名管道
if [[ ! -p "$console_path" ]]; then
rm -f "$console_path"
mkfifo "$console_path"
fi
# 启动分片
# 分片配置路径应为 <persistent_storage_root>/<conf_dir>/<cluster>/<shard>/server.ini
# 这里的配置最终形成的路径实际为 ////clutser/shard/server.ini
# 这在 linux 环境下等价于 /cluster/shard/server.ini
./dontstarve_dedicated_server_nullrenderer_x64 \
-skip_update_server_mods \
-monitor_parent_process $$ \
-persistent_storage_root / \
-conf_dir / \
-ugc_directory "$UGC_PATH" \
-cluster "$(basename $CLUSTER_PATH)" \
-shard "$shard" <>"$console_path" | sed -u "s/^/$shard: /" &
# cloudserver 模式下 TERM 后不会自动终止进程,暂时不用此模式
# -cloudserver 3<>"$console_path" 4>>"$shard_path/fd4" 5>>"$shard_path/fd5"
done
wait