-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmcltool
More file actions
executable file
·445 lines (356 loc) · 12.5 KB
/
mcltool
File metadata and controls
executable file
·445 lines (356 loc) · 12.5 KB
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
#!/bin/bash
## TODO: Make a better usage()
## TODO: Possible code cleanup
GAME_DIR="$HOME/.mclauncher"
BASE_DIR="$GAME_DIR/nofollow"
BACK_DIR="$BASE_DIR/backups"
LWJGL_DIR="$BASE_DIR/lwjgl"
TEXTP_DIR="$BASE_DIR/texturepacks"
MCLNCH_URL="http://s3.amazonaws.com/MinecraftDownload/launcher/minecraft.jar"
LWJGL_URL="http://www.newdawnsoftware.com/jenkins/view/LWJGL/job/LWJGL/lastStableBuild/"
tolower() {
echo "$@" | tr '[A-Z]' '[a-z]'
}
COMMAND="$(tolower $1)"
MCNAME="$2"
shift 2
trap clean_exit SIGINT SIGTERM
# If setup hasn't been completed and the command isn't 'setup' or 'help' error
if [ ! -d "$BASE_DIR" ] && [ "$COMMAND" != "setup" -a "$COMMAND" != "help" ]; then
echo "ERROR: The minecraft launcher hasn't been set-up. Please run this tool with the parameter 'setup' before attempting to continue."
exit 1
fi
clean_exit() {
if [ "$COMMAND" = "setup" ]; then
rm -rf $GAME_DIR
fi
exit 1
}
# getver [mcdir]
getver() {
echo "$(unzip -qqp $1/bin/minecraft.jar net/minecraft/client/Minecraft.class | grep -Eao "Minecraft Minecraft [A-Za-z0-9\.-]+" | cut -c21-)"
}
# try_makeinfo [mcdir] [mcname]
try_makeinfo() {
[ -e "$1/.mcinfo" ] && return 1
[ ! -e "$1/bin/minecraft.jar" ] && return 1
echo "$2) $(getver $1) : " > $1/.mcinfo
return 0
}
mcl_usage() {
echo \
"Usage: $0 COMMAND [OPTIONS]...
Commands:
help - Displays this message.
setup - Sets up everything needed for first time use.
make,new MCNAME [DERIVED] - Creates a new minecraft install with the name 'mcname'. By default it is derived from 'vanilla'.
mv,move,rename MCNAME NEWNAME - Renames 'MCNAME' to 'NEWNAME'.
rm,remove,delete MCNAME - Removes 'MCNAME'.
ls,list [MCNAME] - Prints out a list of all the different versions currently installed.
install FILES - Attempts to install all the mods passed as parameters. Mods following a '-m' are installed to the mods folder rather than the jar. You can use the '-M' flag to have a list of mods to be installed to the mods folder. A subsequent '-M' will end the list.
link [MCNAME] - If mcname is specified it links the install to ~/.minecraft, otherwise it prints the name of the install currently linked.
backup MCNAME VER - Makes a backup of minecraft.jar for 'MCNAME' with the name 'VER'.
restore MCNAME [-h] [VER] - Restores the minecraft.jar to the specified version. If no version is specified the current version number is restored. All mods in the mods folder are deleted, but folders and configs remain intact. If you would like everything in the mods folder removed use the '-h' flag.
update_lwjgl MCNAME - Attempts to download and install the most recent stable build of lwjgl to MCNAME. If no internet connection is found an attempt will be made to install a local copy if one is present. The local copy is kept in ~/.mclauncher/nofollow/ and should be the only zip in that directory. The general filename structure is lwjgl-VERSION_REVISION.zip
deinit MCNAME [-h] - Deinitializes the launcher and places MCNAME in ~/.minecraft. If '-h' isn't specified all the other minecraft installs are moved to ~/mclauncher, otherwise everything else is deleted."
}
mcl_setup() {
# Error if setup seems to have already been called
if [ -d "$GAME_DIR" ]; then
echo "INFO: Everything is already setup, or ~/.mclauncher is already occupied."
exit 1
fi
mkdir -p $BACK_DIR
mkdir $TEXTP_DIR
mkdir $GAME_DIR/vanilla
INPUT="vanilla"
if [ -d "$HOME/.minecraft" ]; then
echo "INFO: It appears that ~/.minecraft already exists. This launcher requires at least one vanilla minecraft version(i.e. no mods) be available for everything to function correctly. If this is a vanilla version it can be cleanly migrated for use within this launcher. Otherwise you will have to create a vanilla version at a later date for full functionality."
while [ "$INPUT" != "y" -a "$INPUT" != "n" ]; do
printf "Is this a vanilla version? [y/n]: "
read -r INPUT
INPUT="$(tolower $INPUT)"
done
if [ "$INPUT" == "n" ]; then
echo "INFO: Since this will not be a vanilla install you must specify another name to use. This can be changed at any time by running this launcher tool with the 'rename' parameter. The launcher also won't be able to determine what mods are currently installed. To create a fresh vanilla install later simply run 'minecraft vanilla'."
INPUT="vanilla"
while [ "$INPUT" == "vanilla" ]; do
printf "Please enter a name for this install: "
read -r INPUT
[ "$INPUT" == "vanilla" ] && echo "ERROR: Name cannot be 'vanilla'."
done
fi
if [ -h "$HOME/.minecraft" ]; then
cp -R "$(readlink $HOME/.minecraft)" $GAME_DIR/$INPUT
unlink $HOME/.minecraft
else
mv $HOME/.minecraft $GAME_DIR/$INPUT
fi
mv $GAME_DIR/$INPUT/texturepacks $TEXTP_DIR
echo "INFO: Migrated install to '$INPUT'."
fi
curl -# $MCLNCH_URL > $GAME_DIR/minecraft.jar
ln -s $GAME_DIR/$INPUT $HOME/.minecraft
ln -s $TEXTP_DIR $GAME_DIR/$INPUT/texturepacks
try_makeinfo $GAME_DIR/$INPUT $INPUT
echo "INFO: Setup is complete, enjoy."
}
mcl_new() {
if [ -z "$MCNAME" ]; then
echo "ERROR: No name specified."
exit 1
fi
[ -z "$1" ] && MCDERIVED="vanilla" || MCDERIVED="$1"
if [ ! -e "$GAME_DIR/$MCDERIVED/.mcinfo" ]; then
echo "ERROR: Unable to create '$MCNAME' from '$MCDERIVED'. Either '$MCDERIVED' doesn't exist, or hasn't been set-up properly."
exit 1
fi
cp -R $GAME_DIR/$MCDERIVED $GAME_DIR/$MCNAME
sed -i "s/.*)/$MCNAME)/" $GAME_DIR/$MCNAME/.mcinfo
}
mcl_rename() {
if [ -z "$MCDIR" ]; then
echo "ERROR: There is no install with the name '$MCNAME'."
exit 1
elif [ "$MCNAME" = "vanilla" ]; then
echo "ERROR: Please don't rename vanilla."
exit 1
fi
mv $GAME_DIR/$MCNAME $GAME_DIR/$1
sed -i "s/.*)/$1)/" $GAME_DIR/$1/.mcinfo
}
mcl_delete() {
if [ "$MCNAME" = "vanilla" ]; then
echo "ERROR: Please don't delete vanilla."
exit 1
fi
[ -n "$MCDIR" ] && rm -r $MCDIR
}
mcl_list() {
if [ -n "$MCNAME" ]; then
[ -n "$MCDIR" ] && cat $MCDIR/.mcinfo
exit
fi
cat $GAME_DIR/*/.mcinfo
}
mcl_link() {
if [ -z "$MCDIR" ]; then
echo "$(basename $(readlink $HOME/.minecraft))"
exit
fi
unlink $HOME/.minecraft >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo "ERROR: Unable to unlink ~/.minecraft"
exit 1
fi
ln -s $MCDIR $HOME/.minecraft
}
mcl_install() {
if [ -z "$MCDIR" ]; then
echo "ERROR: There is no install with the name '$MCNAME'."
exit 1
fi
if [ "$MCNAME" = "vanilla" ]; then
echo "ERROR: Please don't install mods to vanilla."
exit 1
fi
MON=0
cat $MCDIR/.mcinfo | tr -d '\n' > $MCDIR/.mcinfo
# Make sure there is a mods directory
[ ! -d "$MCDIR/mods" ] && mkdir $MCDIR/mods
# Store the current directory and make a temporary directory for the extracted minecraft
LSTDIR="$PWD"
TMPDIR=$(mktemp -d --tmpdir="$MCDIR/bin")
cd $TMPDIR
# Extract minecraft and kill META-INF
jar xf ../minecraft.jar
[ -d "META-INF" ] && rm -r META-INF
# See if there are mods already installed
MCINFO="$(cat $MCDIR/.mcinfo)"
[ "$(echo ${MCINFO##* } | wc -c)" != "1" ] && printf ", " >> $MCDIR/.mcinfo
while [ -n "$1" ]; do
# Check if the argument is a flag for a non-jar mod or the start/end of a non-jar mod list
if [ "$1" = "-m" -o "$1" = "-M" ]; then
if [ "$1" = "-M" ]; then
if [ "$MON" = "0" ]; then MON=1
else MON=0 && shift && continue
fi
fi
MPRE="!" && shift
else
# If the non-jar mod list flag isn't set make sure $MPRE is empty
[ "$MON" = "0" -a -n "$MPRE" ] && MPRE=""
fi
MOD="$1"
printf "Installing '%s'... " "$MOD"
[ ! -e "$MOD" ] && MOD="$LSTDIR/$MOD"
# Check if the mod to install is jar or non-jar
if [ "$1" = "-m" -o "$MON" = "1" ]; then
if ! cp "$MOD" $MCDIR/mods >/dev/null 2>&1; then
echo "Failed"
shift && continue
fi
else
if ! unzip -qq -o "$MOD" >/dev/null 2>&1; then
echo "Failed"
shift && continue
fi
fi
# If installation was successful add it to the mcinfo file
MOD="${MOD:0:(-4)}"
printf "%s" "$MPRE${MOD##*/}" >> $MCDIR/.mcinfo
[ -n "$2" ] && printf ", " >> $MCDIR/.mcinfo
echo "Success"
shift
done
echo >> $MCDIR/.mcinfo
jar cf ../minecraft.jar .
rm -r $TMPDIR
}
mcl_backup() {
if [ -z "$MCDIR" ]; then
echo "ERROR: There is no install with the name '$MCNAME'."
exit 1
fi
cp $MCDIR/bin/minecraft.jar $BACK_DIR/$1.jar
}
mcl_restore() {
if [ -z "$MCDIR" ]; then
echo "ERROR: There is no install with the name '$MCNAME'."
exit 1
fi
if [ "$1" = "-h" ]; then
RESTORE_HARDER=1
shift
else
RESTORE_HARDER=0
fi
[ -z "$1" ] && MCVER="$(cut -d' ' -f2 $MCDIR/.mcinfo)" || MCVER="$1"
[ ! -e "$MCVER" ] && MCVER="$BACK_DIR/$MCVER.jar"
if [ ! -e "$MCVER" ]; then
echo "ERROR: No backup found."
exit 1
fi
cp $MCVER $MCDIR/bin/minecraft.jar
[ "$RESTORE_HARDER" = "0" ] &&
rm $MCDIR/mods/*.zip >/dev/null 2>&1 ||
rm -rf $MCDIR/mods/* >/dev/null 2>&1
echo "$MCNAME) $(getver $MCDIR) : " > $MCDIR/.mcinfo
}
mcl_update_lwjgl() {
if [ -z "$MCDIR" ]; then
echo "ERROR: There is no install with the name '$MCNAME'."
exit 1
fi
echo "INFO: Starting LWJGL update for '$MCNAME'..."
if ping -w5 -c1 google.com >/dev/null 2>&1; then
echo "INFO: Checking latest LWJGL version..."
LWJGL_RAW="$(curl -s $LWJGL_URL/?)"
LWJGL_ZIP="$(echo $LWJGL_RAW | grep -Eo 'lwjgl[^<z]+zip' | sed '1q')"
LWJGL_REV="$(echo $LWJGL_RAW | grep -Eo '[0-9]+<b')"
LWJGL_LOC="${LWJGL_ZIP:0:(-4)}_${LWJGL_REV:0:(-2)}.zip"
else
echo "WARNING: No internet connection, trying local copy..."
fi
if [ ! -e "$BASE_DIR/$LWJGL_LOC" ]; then
echo "INFO: Update found! Downloading..."
rm $BASE_DIR/*zip >/dev/null
curl -# $LWJGL_URL/artifact/dist/$LWJGL_ZIP > $BASE_DIR/$LWJGL_LOC
else
echo "INFO: No update found, using local copy..."
LWJGL_LOC="$(ls $BASE_DIR | grep zip)"
if [ -z "$LWJGL_LOC" ]; then
echo "ERROR: No local copy of LWJGL found"
exit 1
fi
fi
echo "INFO: Extracting archive..."
unzip -qq -d $LWJGL_DIR $BASE_DIR/$LWJGL_LOC
echo "INFO: Updating files in '$MCNAME'..."
JAR_FLIST=( "jinput" "lwjgl" "lwjgl_util" )
for jar in "${JAR_FLIST[@]}"; do
cp $LWJGL_DIR/*/jar/$jar.jar $MCDIR/bin/
done
cp $LWJGL_DIR/*/native/linux/*.so $MCDIR/bin/natives/
echo "INFO: Cleaning up..."
rm -r $LWJGL_DIR
echo "INFO: Update completed successfully!"
}
mcl_deinit() {
echo "WARNING: Deinitialzing will make the launcher unusable."
printf "Do you really want to deinitialize mcl? [y/N]: "
read -r INPUT
INPUT="$(tolower $INPUT)"
[ "$INPUT" != "y" ] && exit
if [ "$1" = "-h" ]; then
DEINIT_HARDER=1
shift
else
DEINIT_HARDER=0
fi
if [ ! -d "$GAME_DIR/$MCNAME" ]; then
echo "ERROR: I'm sorry, I'm afraid I can't let you do that $USER." && sleep 5
echo "ERROR: '$MCNAME' doesn't exist so deinit will fail gracefully now, no changes have been made."
exit 1
fi
unlink $HOME/.minecraft
find $GAME_DIR -maxdepth 1 -type d \( ! -name "nofollow" \) -print0 | xargs -0 -I{} unlink "{}/texturepacks"
rm -f $GAME_DIR/*/.mcinfo >/dev/null 2>&1
rm -r $BASE_DIR
mv $GAME_DIR/$MCRESTORE $HOME/.minecraft
mv $TEXTP_DIR $HOME/.minecraft/
mv $GAME_DIR $HOME/mclauncher
if [ "$DEINIT_HARDER" = "1" ]; then
echo "WARNING: You've specified you want to deinit harder. This will completely delete everything except for '$MCNAME' which has been moved to ~/.minecraft."
printf "There is no turning back after this, are you sure you wish to continue? [y/N]: "
read -r INPUT
INPUT="$(tolower $INPUT)"
[ "$INPUT" != "y" ] && exit
rm -r $HOME/mclauncher
echo "INFO: The deed has been done."
fi
}
# If $MCNAME exists then set $MCDIR and attempt to make an info file if it doesn't exist
[ -n "$MCNAME" -a "$MCNAME" != "nofollow" -a -d "$GAME_DIR/$MCNAME" ] && MCDIR=$GAME_DIR/$MCNAME
[ -n "$MCDIR" ] && try_makeinfo $MCDIR $MCNAME
case "$COMMAND" in
help)
mcl_usage
;;
setup)
mcl_setup $@
;;
make|new)
mcl_new $@
;;
rename|move|mv)
mcl_rename $@
;;
delete|remove|rm)
mcl_delete $@
;;
list|ls)
mcl_list $@
;;
link)
mcl_link $@
;;
install)
mcl_install $@
;;
backup)
mcl_backup $@
;;
restore)
mcl_restore $@
;;
update_lwjgl)
mcl_update_lwjgl $@
;;
deinit)
mcl_deinit $@
;;
*)
mcl_usage
exit 1
esac