-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmctools.sh
259 lines (235 loc) · 7.01 KB
/
mctools.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
#!/usr/bin/env bash
AUTO_COMP=(zstd lz4 gzip)
AUTO_COMP_SUF=(zst lz4 gz)
PG_NAME=$(basename $0)
root_check(){
if [ $(whoami) != 'root' ]; then
echo "${PG_NAME}: Permission denied. Must be superuser."
exit 1
fi
}
get_opts(){
if [ ! $1 ]; then
usage
exit 0
fi
while [ $# -gt 0 ]; do
case $1 in
backup)
export MODE=$1
;;
rollback)
export MODE=$1
;;
clean)
export MODE=$1
shift
export BACKUP_DIR=$1
;;
from)
shift
export GAME_DIR=$1
;;
to)
shift
export BACKUP_DIR=$1
;;
use)
shift
export CUST_COMP=$1
;;
*)
usage
exit 0
;;
esac
shift
done
}
var_check(){
# Minecraft service check
if [ "${MODE}" != "clean" ]; then
if [ $(ps aux | grep minecraft-server.jar | grep -v grep | wc -l) -ne 0 ]; then
echo "Minecraft server is running."
echo "Please stop Minecraft server before backup or rollback."
exit 1
fi
fi
# Rollback var swap
if [ "${MODE}" = "rollback" ]; then
swap=${GAME_DIR}
export GAME_DIR=${BACKUP_DIR}
export BACKUP_DIR=${swap}
unset swap
fi
# GAME_DIR check
if [ "${MODE}" != "clean" ]; then
if [ ! ${GAME_DIR} ] || [ ! -d ${GAME_DIR} ]; then
echo "Error: Game directory not exist."
echo "Please check you minecraft directory."
exit 1
fi
fi
# LEVEL_NAME check
if [ "${MODE}" != "clean" ]; then
if [ ! -f ${GAME_DIR}/server.properties ]; then
echo "Error: File server.properties not found."
echo "Please check you minecraft directory."
exit 1
else
export LEVEL_NAME=$(grep level-name ${GAME_DIR}/server.properties | cut -d '=' -f 2)
fi
if [ -z "${LEVEL_NAME}" ]; then
echo "Error: Cannot get the level name."
echo "Plesae check you server.properties."
exit 1
fi
fi
# BACKUP_DIR check
if [ ! ${BACKUP_DIR} ]; then
echo "Error: Backup directory not exist."
echo "Please check you backup directory."
exit 1
elif [ -f ${BACKUP_DIR} ]; then
export BACKUP_FILE=$(basename ${BACKUP_DIR})
elif [ ! -d ${BACKUP_DIR} ]; then
read -p "Backup directory: ${BACKUP_DIR} not exist. Create it? [Y/n] " yn
case ${yn} in
[Nn])
echo "Backup not completed."
exit 1
;;
*)
mkdir -p ${BACKUP_DIR}
;;
esac
fi
# BACKUP_FILE set
if [ "${MODE}" = "backup" ] && [ ! ${BACKUP_FILE}]; then
export BACKUP_FILE=$(date +%Y%m%d_%H%M%S)-${LEVEL_NAME}.tar
fi
}
comp_var_check(){
# CUST_COMP check
if [ ! ${CUST_COMP} ]; then
for x in ${AUTO_COMP[@]}; do
type ${x} > /dev/null
if [ $? = 0 ]; then
export CUST_COMP=${x}
break
fi
done
fi
if [[ ! "${AUTO_COMP[@]}" =~ "${CUST_COMP}" ]]; then
echo "Error: Unsuported compressino algo."
exit 2
else
type ${CUST_COMP} > /dev/null
if [ $? != 0 ]; then
echo "Error: ${CUST_COMP} not found. Install it before use."
exit 1
fi
fi
# CUST_COMP_SUF check
for x in ${!AUTO_COMP[@]}; do
if [ "${AUTO_COMP[x]}" = "${CUST_COMP}" ]; then
export CUST_COMP_SUF=${AUTO_COMP_SUF[x]}
fi
done
}
backup(){
comp_var_check
echo "Backup start."
echo "Backing up ${BACKUP_FILE}..."
cd ${GAME_DIR}
tar -I ${CUST_COMP} -cpf ${BACKUP_DIR}/${BACKUP_FILE}.${CUST_COMP_SUF} ${LEVEL_NAME}
echo "Backup completed."
}
rollback(){
root_check
echo "Rollback start."
# Choose backup file (Interactive)
if [ ! ${BACKUP_FILE} ]; then
echo "Choose a backup file you want to rollback: "
ls -1t ${BACKUP_DIR} | nl -n rn -s '. '
read -p "You choose: " num
if [ $(ls -1t ${BACKUP_DIR} | wc -l) -lt ${num} ]; then
echo "Error: Invalid number."
exit 2
fi
export BACKUP_FILE=$(ls -1t ${BACKUP_DIR} | head -${num} | tail -1)
fi
# Clean backup directory
read -p "We will OVERWRITE ${GAME_DIR}/${LEVEL_NAME} ! Contiune? [N/y] " yn
case ${yn} in
[Yy])
echo "Cleaning ${GAME_DIR}/${LEVEL_NAME}..."
rm -rf ${GAME_DIR}/${LEVEL_NAME}
echo "Cleaned completed."
;;
*)
echo "World directory will not clean."
exit 0
;;
esac
# Determine compression algo
export CUST_COMP=$(file --mime-type ${BACKUP_DIR}/${BACKUP_FILE} | grep -oE 'x-(zstd|lz4|xz|bzip2|gzip)' | cut -d '-' -f 2)
type ${CUST_COMP} > /dev/null
if [ $? = 0 ]; then
echo "Rolling back ${BACKUP_FILE}..."
tar -I ${CUST_COMP} -xpf ${BACKUP_DIR}/${BACKUP_FILE} -C ${GAME_DIR}
else
echo "Error: ${CUST_COMP} not found. Install it before use."
exit 1
fi
echo "Rollback completed."
}
clean(){
echo "Clean start."
# Backup files amount less than or equal 3
if [ $(ls -1t ${BACKUP_DIR} | wc -l ) -le 3 ]; then
echo "No need to clean."
exit 1
fi
# Clean backup directory (Interactive)
echo "We will clean your backup files and only stay the NEWEST 3 backup!"
echo "These files will be removed from ${BACKUP_DIR}: "
ls -1t ${BACKUP_DIR} | tail -n +4 | nl -n rn -s '. '
read -p "Contiune clean? [N/y] " yn
case ${yn} in
[Yy])
while [ $(ls -1t ${BACKUP_DIR} | wc -l) -gt 3 ]; do
export BACKUP_FILE=$(ls -1t ${BACKUP_DIR} | tail -1)
rm -f ${BACKUP_DIR}/${BACKUP_FILE}
echo "Removed ${BACKUP_FILE}."
done
;;
*)
echo "Backup files will not clean."
exit 0
;;
esac
echo "Clean completed."
}
usage(){
echo "${PG_NAME}: Minecraft server backup and rollback tools"
echo "Usage: ${PG_NAME} backup from [ GAME_DIR ] to [ BACKUP_DIR ] < use [ zstd | lz4 | gzip ] >"
echo " ${PG_NAME} rollback from [ BACKUP_DIR ] to [ GAME_DIR ]"
echo " ${PG_NAME} clean [ BACKUP_DIR ]"
echo " ${PG_NAME} help"
echo ""
echo "where GAME_DIR is your Minecraft game directory (not world directory)"
echo " BACKUP_DIR is your backup directory"
echo ""
echo "when return 0 means normal exit"
echo " return 1 means file or dir problems"
echo " return 2 means parameters problems"
echo ""
echo "type '${PG_NAME} help' for this menu"
}
main(){
get_opts $*
var_check
${MODE}
}
main $*