-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WatchWolfSetup.sh
280 lines (230 loc) · 12.1 KB
/
WatchWolfSetup.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#!/bin/bash
echo "Starting WatchWolfSetup..."
opt=""
branch="master"
no_startup=0
no_spigot=0
num_processes=$((`nproc --all` - 2))
base_path="$HOME/WatchWolf"
while [[ "$#" -gt 0 ]]; do
case $1 in
--dev) branch="dev" ;;
--threads) num_processes="$2"; shift ;;
--path) base_path="$2"; shift ;;
--disable-startup) no_startup=1 ;;
--skip-spigot-build) no_spigot=1 ;;
--build) opt="build" ;;
--install) opt="install" ;;
--uninstall) opt="uninstall" ;;
--run) opt="run" ;;
*) echo "[e] Unknown parameter passed: $1" >&2 ; exit 1 ;;
esac
shift
done
if [ $num_processes -lt 1 ]; then
num_processes=1 # at least 1 process
fi
# target paths
servers_manager_path="$base_path/ServersManager"
clients_manager_path="$base_path/ClientsManager"
# ask for sudo
sudo echo "" # this will prompt the sudo password input (if not sudo)
# run the desider operation
case "$opt" in
"build" )
# keep previous servers/plugins
tmpdir=`mktemp -d`
cp -r "$servers_manager_path/server-types/" "$tmpdir" 2>/dev/null
cp -r "$servers_manager_path/usual-plugins/" "$tmpdir" 2>/dev/null
# git needs empty folders
sudo rm -rf "$servers_manager_path" 2>/dev/null
sudo rm -rf "$clients_manager_path" 2>/dev/null
# get git files
git clone --branch "$branch" https://github.com/rogermiranda1000/WatchWolf-ServersManager.git "$servers_manager_path"
git clone --branch "$branch" https://github.com/rogermiranda1000/WatchWolf-Client.git "$clients_manager_path"
# restore back previous servers/plugins (if any)
cp -r "$tmpdir/server-types/" "$servers_manager_path" 2>/dev/null
cp -r "$tmpdir/usual-plugins/" "$servers_manager_path" 2>/dev/null
mkdir -p "$servers_manager_path/server-types/Spigot"
mkdir -p "$servers_manager_path/server-types/Paper"
if [ `docker -v >/dev/null 2>&1 ; echo $?` -ne 0 ]; then
echo "[e] Docker is not installed, or is currently stopped. Check https://docs.docker.com/get-docker/." >&2
exit 1
fi
# ServersManager dependencies
sudo docker pull openjdk:8
sudo docker pull openjdk:16
sudo docker pull openjdk:17
sudo docker pull ubuntu
if [ $no_spigot -eq 0 ]; then
dos2unix "$servers_manager_path/SpigotBuilder.sh" "$servers_manager_path/PaperBuilder.sh"
source "$servers_manager_path/SpigotBuilder.sh" # getAllVersions/buildVersion
source "$servers_manager_path/PaperBuilder.sh" # getAllPaperVersions/buildPaperVersion
# download the first <num_processes> Spigot versions
num_downloading_containers=`getAllVersions | grep -c $'\n'`
num_pending_containers=$(($num_downloading_containers > $num_processes ? $num_downloading_containers - $num_processes : 0))
while read version; do
buildVersion "$servers_manager_path/server-types/Spigot" "$version" >/dev/null 2>&1
done <<< "$(getAllVersions | head -n $num_processes)" # get the first <num_processes> versions
fi
# download usual plugins
while read usual_plugin; do
usual_plugin_name=`echo "$usual_plugin" | jq -r -c '.name + "-" + .version + "-" + .min_mc_version + "-" + .max_mc_version + ".jar"'`
usual_plugin_url=`echo "$usual_plugin" | jq -r -c '.url'`
# @ref https://github.com/rogermiranda1000/WatchWolf-ServersManager/blob/fdd45da8fa787b201a48ccca565a4e9f1415b7c3/ServersManager.sh#L56
spigot_id=`echo "$usual_plugin_url" | grep -o -P '(?<=spigotmc.org/resources/)[^/]+' | grep -o -P '\d+$'`
if [ -z "$spigot_id" ]; then
wget -O "$servers_manager_path/usual-plugins/$usual_plugin_name" "$usual_plugin_url"
else
# Spigot plugin; get plugin from Spiget website
spigot_plugin_name=`wget -q -O - "https://api.spiget.org/v2/resources/$spigot_id" | jq -r .name`
# TODO download a specific version doesn't work
#spigot_plugin_version=`echo "$usual_plugin_url" | grep -o -P '(?<=/download\?version=)[^/]+$'`
#if [ -z "$spigot_plugin_version" ]; then
usual_plugin_url="https://api.spiget.org/v2/resources/$spigot_id/download"
#else
# usual_plugin_url="https://api.spiget.org/v2/resources/$spigot_id/versions/$spigot_plugin_version/download"
#fi
wget -O "$servers_manager_path/usual-plugins/$usual_plugin_name" "$usual_plugin_url"
fi
done <<< `curl -s -N https://watchwolf.dev/api/v1/usual-plugins | jq -c '."usual-plugins" | .[]'` # all usual plugins urls
# WatchWolf Server as usual-plugins
watchwolf_server_versions_base_path="https://watchwolf.dev/versions"
web_contents=`wget -q -O - "$watchwolf_server_versions_base_path"`
higher_version=`echo "$web_contents" | grep -o -P '(?<=WatchWolf-)[\d.]+(?=-)' | sort --reverse --version-sort --field-separator=. | head -1` # get the current higher version
higher_version_file=`echo "$web_contents" | grep -o -P "WatchWolf-${higher_version//./\\.}-[\d.]+-[\d.]+\.jar"`
wget "$watchwolf_server_versions_base_path/$higher_version_file" -P "$servers_manager_path/usual-plugins"
# ClientsManager dependencies
sudo docker pull nikolaik/python-nodejs
sudo docker build --tag clients-manager "$clients_manager_path"
if [ $no_spigot -eq 0 ]; then
# all ended; wait for the Spigot versions to finish
current_downloading_containers=`sudo docker container ls -a | grep 'Spigot_build_' -c`
dots=""
while [ $(($current_downloading_containers + $num_pending_containers)) -gt 0 ]; do
while read version; do
if [ ! -z "$version" ]; then
# still versions remaining, and there's a place to run them
buildVersion "$servers_manager_path/server-types/Spigot" "$version" >/dev/null 2>&1
((num_pending_containers--))
((current_downloading_containers++))
fi
done <<< "$( getAllVersions | tail -n $num_pending_containers | head -n $(($num_processes > $current_downloading_containers ? $num_processes - $current_downloading_containers : 0)) )" # get enought versions of the remaining versions to fill the threads
echo "Spigot containers still running (this process can take up to 1 hour in an average computer)"
echo -ne "Waiting all Spigot containers to finish$dots ($(( $num_downloading_containers-$num_pending_containers-$current_downloading_containers ))/$num_downloading_containers) \r"
dots="$dots."
if [ ${#dots} -gt 3 ]; then
dots=""
fi
sleep 15
current_downloading_containers=`sudo docker container ls -a | grep 'Spigot_build_' -c`
done
# Spigot ended, now wait for Paper
while read version; do
if [ ! -z "$version" ]; then
# still versions remaining, and there's a place to run them
buildPaperVersion "$servers_manager_path/server-types/Paper" "$version" #>/dev/null 2>&1
fi
done <<< "$(getAllPaperVersions)"
fi
echo -ne '\nWatchWolf built.\n'
;;
"install" )
if [ "$0" == "/usr/bin/watchwolf" ]; then
echo "[e] 'bash WatchWolfSetup.sh --install' can only be executed from the original path. Check that location with 'stat /usr/bin/watchwolf'." >&2
exit 1
fi
wsl=`cat /proc/version | grep -i -c 'microsoft'`
script_path="$(pwd)/$0"
# accessible from everywhere
chmod +x "$script_path"
sudo ln -sf "$script_path" /bin/watchwolf # run WatchWolf from any place
if [ $no_startup -eq 0 ]; then
# run at startup
if [ $wsl -eq 0 ]; then
echo "[w] Install has only been tested with WSL. Report any problem in https://github.com/watch-wolf/WatchWolf/issues" >&2
# create service
service_contents=$(cat <<-END
[Unit]
Description=Launches WatchWolf ServersManager and WatchWolf ClientsManager
[Service]
ExecStart=bash "$script_path" --run --path "$base_path"
[Install]
WantedBy=multi-user.target
END
)
sudo bash -c "echo '$service_contents' > /etc/systemd/system/watchwolf.service" # create service
sudo systemctl enable watchwolf # init service
else
# WSL
echo "Running WatchWolf at startup will prompt a CMD asking for the WSL password each time."
echo "To make this task more pleasant, this script will disable the WSL admin password."
echo "Do you want to disable the WSL password? (D)isable"
echo "Do you want to keep the WSL password, thus prompting the CMD on each startup? (K)eep"
echo "Do you want to exit (don't launch WatchWolf at startup; manually run './WatchWolf --run' each time)? (E)xit"
read -p 'D/K/E: ' option
while [ `echo "$option" | grep -i -E -c '^[DKE]'` -eq 0 ]; do
read -p 'Unknown option. Use (D)isable, (K)eep, or (E)xit: ' option
done
if [ `echo "$option" | grep -i -E -c '^[DK]'` -ne 0 ]; then # Exit?
if [ `echo "$option" | grep -i -E -c '^D'` -ne 0 ]; then
# don't keep; disable sudo password
sudo bash -c "echo '`whoami` ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/`whoami`" && sudo chmod 0440 /etc/sudoers.d/`whoami` # @ref https://www.folkstalk.com/tech/ubuntu-wsl-disable-sudo-password-prompt-with-code-examples/
echo "WSL password disabled"
fi
# create "service"
base=`/mnt/c/Windows/System32/cmd.exe /c 'echo %USERPROFILE%' | sed 's/\r$//'` # get the base path
base=`echo "$base" | sed 's_\\\\_/_g' | sed 's_C:/_/mnt/c/_g'` # in WSL the directory delimiter is '/' (not '\'), and 'C:' is '/mnt/c'
windows_start_folder="$base/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup" # @ref https://www.thewindowsclub.com/startup-folder-in-windows-8
echo "wsl bash \"$script_path\" --run --path \"$base_path\"" > "$windows_start_folder/WatchWolf.bat"
echo "Launch on startup done"
fi
fi
fi
;;
"uninstall" )
wsl=`cat /proc/version | grep -i -c 'microsoft'`
sudo rm /bin/watchwolf
if [ $wsl -eq 0 ]; then
echo "[w] Uninstall has only been tested with WSL. Report any problem in https://github.com/watch-wolf/WatchWolf/issues" >&2
sudo rm /etc/systemd/system/watchwolf.service
else
base=`/mnt/c/Windows/System32/cmd.exe /c 'echo %USERPROFILE%' | sed 's/\r$//'`
base=`echo "$base" | sed 's_\\\\_/_g' | sed 's_C:/_/mnt/c/_g'`
windows_start_folder="$base/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup"
sudo rm "$windows_start_folder/WatchWolf.bat"
fi
;;
"run" )
dots=""
while [ `docker -v >/dev/null 2>&1 ; echo $?` -ne 0 ]; do
echo -ne "Waiting Docker to start$dots \r"
dots="$dots."
if [ ${#dots} -gt 3 ]; then
dots=""
fi
sleep 15
done
echo ""
# run ServersManager
wsl_mode(){ echo "echo 'Hello world'" | powershell.exe >/dev/null 2>&1; return $?; }
get_ip(){ wsl_mode; if [ $? -eq 0 ]; then echo "(Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias Ethernet).IPAddress" | powershell.exe 2>/dev/null | tail -n2 | head -n1; else hostname -I | awk '{print $1}';fi }
sudo docker run --privileged=true -i --rm --name ServersManager -p 8000:8000 -v /var/run/docker.sock:/var/run/docker.sock -v "$servers_manager_path":"$servers_manager_path" --env MACHINE_IP=$(get_ip) --env PUBLIC_IP=$(curl ifconfig.me) --env WSL_MODE=$(wsl_mode ; echo $? | grep -c 0) ubuntu:latest sh -c "echo '[*] Preparing ServersManager...' ; apt-get -qq update ; DEBIAN_FRONTEND=noninteractive apt-get install -y socat docker.io gawk procmail dos2unix jq unzip wget >/dev/null ; echo '[*] ServersManager ready.' ; cd $servers_manager_path ; dos2unix ServersManager.sh ServersManagerConnector.sh SpigotBuilder.sh PaperBuilder.sh ConnectorHelper.sh ; chmod +x ServersManager.sh ServersManagerConnector.sh SpigotBuilder.sh PaperBuilder.sh ConnectorHelper.sh ; rm ServersManager.lock 2>/dev/null ; socat -d -d tcp-l:8000,pktinfo,keepalive,keepidle=10,keepintvl=10,keepcnt=100,ignoreeof,fork system:'bash ./ServersManagerConnector.sh'" >/dev/null 2>&1 & disown
# run ClientsManager
sudo docker run -i --rm --name ClientsManager -p 7000-7199:7000-7199 --env MACHINE_IP=$(get_ip) --env PUBLIC_IP=$(curl ifconfig.me) clients-manager:latest >/dev/null 2>&1 & disown
dots=""
while [ `sudo docker container ls -a | grep -c -E 'ClientsManager|ServersManager'` -lt 2 ]; do
echo -ne "Waiting Docker containers to start$dots \r"
dots="$dots."
if [ ${#dots} -gt 3 ]; then
dots=""
fi
sleep 1 # wait
done
echo -ne "\nWatchWolf started.\n" # TODO wait for containers to install
;;
* )
echo "[e] No operation. Run 'bash WatchWolfSetup.sh --build', 'bash WatchWolfSetup.sh --install', 'bash WatchWolfSetup.sh --uninstall' or 'bash WatchWolfSetup.sh --run'" >&2
exit 1
;;
esac