]> git.xonotic.org Git - xonotic/netradiant.git/blob - gamepack-manager
a bunch of gamepack-manager udpates
[xonotic/netradiant.git] / gamepack-manager
1 #! /usr/bin/env bash
2
3 # get usage help this way:
4 # ./gamepack_manager -h
5
6 : "${CP:=cp -v}"
7 : "${CP_R:=cp -r --preserve=timestamps}"
8 : "${GIT:=git}"
9 : "${SVN:=svn}"
10 : "${WGET:=wget}"
11 : "${ECHO:=echo}"
12 : "${MKDIR:=mkdir -v}"
13 : "${MKDIR_P:=mkdir -vp}"
14 : "${RM_R:=rm -vrf}"
15 : "${MV:=mv -v}"
16 : "${TAR:=tar}"
17 : "${UNZIPPER:=unzip}"
18
19 set -e
20
21 default_download_dir='build/download'
22 default_install_dir='build'
23
24 games_dir='games'
25 pack_suffix='Pack'
26
27 free_license_list='BSD GPL'
28
29 printRawDB () {
30 cat <<\EOF
31 #######################################################
32 #                                                     #
33 #  IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT  #
34 #                                                     #
35 #   Use two whitespaces or more as column separator   #
36 #                                                     #
37 #######################################################
38
39 #######################################################
40 # Obsolete packs                                      #
41 #######################################################
42
43 # Quake2World was renamed as Quetoo
44 # Other gamepacks have better version available
45
46 # OpenArena     unknown      zip     http://ingar.intranifty.net/files/netradiant/gamepacks/OpenArenaPack.zip
47 # Quake         proprietary  zip     http://ingar.intranifty.net/files/netradiant/gamepacks/QuakePack.zip
48 # Quake2World   GPL          svn     svn://jdolan.dyndns.org/quake2world/trunk/gtkradiant
49 # Tremulous     proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/TremulousPack/branches/1.5/
50 # Unvanquished  unknown      zip     http://ingar.intranifty.net/gtkradiant/files/gamepacks/UnvanquishedPack.zip
51 # Warsow        GPL          svn     https://svn.bountysource.com/wswpack/trunk/netradiant/games/WarsowPack/
52 # Warsow        GPL          zip     http://ingar.intranifty.net/files/netradiant/gamepacks/WarsowPack.zip
53
54 #######################################################
55 # Usable packs                                        #
56 #######################################################
57
58 DarkPlaces      GPL          svn     svn://svn.icculus.org/gtkradiant-gamepacks/DarkPlacesPack/branches/1.5/
59 Doom3           proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/Doom3Pack/branches/1.5/
60 ET              proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/ETPack/branches/1.5/
61 Heretic2        proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/Her2Pack/branches/1.5/
62 JediAcademy     proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/JAPack/branches/1.5/
63 Neverball       proprietary  zip     http://ingar.intranifty.net/files/netradiant/gamepacks/NeverballPack.zip
64 Nexuiz          GPL          gitdir  git://git.icculus.org/divverent/nexuiz.git misc/netradiant-NexuizPack master
65 OpenArena       GPL          git     https://github.com/NeonKnightOA/oagamepack.git
66 Osirion         GPL          zip     http://ingar.intranifty.net/files/netradiant/gamepacks/OsirionPack.zip
67 Prey            proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/PreyPack/trunk/
68 Q3              proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/Q3Pack/trunk/ 29
69 Quake2          proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/Q2Pack/branches/1.5/
70 Quake4          proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/Q4Pack/branches/1.5/
71 Quake           GPL          zip     http://ingar.intranifty.net/files/netradiant/gamepacks/Quake1Pack.zip
72 Quetoo          GPL          svn     svn://svn.icculus.org/gtkradiant-gamepacks/QuetooPack/branches/1.5/
73 Tremulous       proprietary  zip     http://ingar.intranifty.net/files/netradiant/gamepacks/TremulousPack.zip
74 TurtleArena     proprietary  git     https://github.com/Turtle-Arena/turtle-arena-radiant-pack.git
75 UFOAI           proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/UFOAIPack/branches/1.5/
76 Unvanquished    BSD          git     https://github.com/Unvanquished/unvanquished-mapeditor-support.git
77 Warsow          GPL          git     https://github.com/Warsow/NetRadiantPack.git
78 Wolf            proprietary  svn     svn://svn.icculus.org/gtkradiant-gamepacks/WolfPack/branches/1.5/
79 Xonotic         GPL          git     https://gitlab.com/xonotic/netradiant-xonoticpack.git
80 EOF
81 }
82
83 sanitizeDB () {
84         sed -e 's/#.*//;s/[ \t][ \t][ \t]*/\t/g;s/^[ \t]*//;s/[ \t]*$//' \
85         | grep -v '^$'
86 }
87
88 inList () {
89         [ "$(grep "^${1}$")" = "${1}" ]
90 }
91
92 printList () {
93         echo "${1}" \
94         | tr ' ' '\n' \
95         | grep -v '^$' \
96         | sort -u
97 }
98
99 dedupeList () {
100         printList "${1}" \
101         | tr '\n' ' ' \
102         | sed -e 's/ $//'
103 }
104
105 printGamePackDB () {
106         printRawDB \
107         | sanitizeDB
108 }
109
110 printLicenseList () {
111         printGamePackDB \
112         | awk '{ print $2 }' \
113         | sort -u
114 }
115
116 printNameList () {
117         printGamePackDB \
118         | awk '{ print $1 }' \
119         | sort -u
120 }
121
122 printNameListByLicense () {
123         local arg_license_list
124         local license_list
125         local license
126
127         arg_license_list="${1}"
128         license_list=''
129
130         for license in ${arg_license_list}
131         do
132                 case "${license}" in
133                         'none')
134                                 break
135                                 ;;
136                         'all')
137                                 license_list="$(printLicenseList)"
138                                 break
139                                 ;;
140                         'free')
141                                 license_list="${license_list} ${free_license_list}"
142                                 ;;
143                         *)
144                                 if printLicenseList | inList "${license}"
145                                 then
146                                         license_list="${license_list} ${license}"
147                                 else
148                                         printError "unknown license: ${license}"
149                                 fi
150                                 ;;
151                 esac
152         done
153
154         license_list="$(dedupeList "${license_list}")"
155
156         for license in ${license_list}
157         do
158                 printGamePackDB \
159                 | awk '$2 == "'"${license}"'"' \
160                 | awk '{ print $1 }'
161         done
162 }
163
164 printNameListByName () {
165         local argname_list
166         local name_list
167         local name
168
169         argname_list="${1}"
170         name_list=''
171
172         for name in ${argname_list}
173         do
174                 case "${name}" in
175                         'none')
176                                 break
177                                 ;;
178                         'all')
179                                 local name_list
180                                 name_list="$(printNameList)"
181                                 break
182                                 ;;
183                         *)
184                                 if printNameList | inList "${name}"
185                                 then
186                                         local name_list
187                                         name_list="${name_list} ${name}"
188                                 else
189                                         printError "unknown name: ${name}"
190                                 fi
191                                 ;;
192                 esac
193         done
194
195         name_list="$(dedupeList "${name_list}")"
196
197         for name in ${name_list}
198         do
199                 printGamePackDB \
200                 | awk '$1 == "'"${name}"'"' \
201                 | awk '{ print $1 }'
202         done
203 }
204
205 printPackLine () {
206         local name
207
208         name="${1}"
209
210         printGamePackDB \
211         | awk '$1 == "'"${name}"'"'
212 }
213
214 getValue () {
215         local name
216         local key
217
218         name="${1}"
219         key="${2}"
220
221         printPackLine "${name}" \
222         | awk '{ print $'"${key}"' }'
223 }
224
225 downloadExtraUrls ()
226 {
227         local dir
228
229         dir="${1}"
230
231         if [ -f "${dir}/extra-urls.txt" ]
232         then
233                 while IFS='     ' read -r FILE URL
234                 do
235                         (
236                                 ${WGET} -O "${dir}/${FILE}" "${URL}"
237                         ) </dev/null
238                 done < "${dir}/extra-urls.txt"
239         fi
240 }
241
242 downloadPack () {
243         local download_dir
244         local name
245         local license
246         local source_type
247         local source_url
248         local pack
249         local reference
250         local subdir
251         local branch
252
253         download_dir="${1}"
254         name="${2}"
255
256         license="$(getValue "${name}" '2')"
257         source_type="$(getValue "${name}" '3')"
258         source_url="$(getValue "${name}" '4')"
259
260         pack="${name}${pack_suffix}"
261
262         ${MKDIR_P} "${download_dir}"
263
264         (
265                 cd "${download_dir}"
266
267                 ${ECHO} ''
268                 ${ECHO} "Available pack: ${pack}"
269                 ${ECHO} "  License: ${license}"
270                 ${ECHO} "  Download via ${source_type} from ${source_url}"
271                 ${ECHO} ''
272
273                 if [ -d "${download_dir}/${pack}" ]
274                 then
275                         ${ECHO} "Updating ${name}…"
276                 else
277                         ${ECHO} "Downloading ${pack}…"
278                 fi
279
280                 case "${source_type}" in
281                         'svn')
282                                 reference="$(getValue "${name}" '5')"
283                                 if [ -z "${reference}" ]
284                                 then
285                                         reference='HEAD'
286                                 fi
287
288                                 if [ -d "${pack}" ]
289                                 then
290                                         if [ -d "${pack}/.git" ]
291                                         then
292                                                 (
293                                                         cd "${pack}"
294                                                         ${GIT} svn fetch
295                                                 )
296                                         else
297                                                 ${SVN} update -r"${reference}" "${pack}"
298                                         fi
299                                 else
300                                         ${SVN} checkout -r"${reference}" "${source_url}" "${pack}" \
301                                         || ${GIT} svn clone "${source_url}" "${pack}"
302                                 fi
303                                 ;;
304                         'zip')
305                                 ${RM_R} 'zipdownload'
306                                 ${MKDIR} 'zipdownload'
307                                 (
308                                         cd 'zipdownload'
309                                         ${WGET} "${source_url}"
310                                         ${UNZIPPER} './'*.zip
311                                 )
312                                 ${RM_R} "${pack}"
313                                 ${MKDIR} "${pack}"
314                                 ${MV} 'zipdownload/'*'/'* "${pack}/"
315                                 ${RM_R} 'zipdownload'
316                                 ;;
317                         'gitdir')
318                                 local subdir="$(getValue "${name}" '5')"
319                                 local branch="$(getValue "${name}" '6')"
320                                 ${RM_R} "${pack}"
321                                 ${GIT} archive --remote="${source_url}" --prefix="${pack}/" "${branch}":"${subdir}" \
322                                 | ${TAR} xvf -
323                                 ;;
324                         'git')
325                                 if [ -d "${pack}" ]
326                                 then
327                                         (
328                                                 cd "${pack}"
329                                                 ${GIT} pull
330                                         )
331                                 else
332                                         ${GIT} clone "${source_url}" "${pack}"
333                                 fi
334                                 ;;
335                 esac
336
337                 if [ -d "${download_dir}/${pack}" ]
338                 then
339                         (
340                                 cd "${download_dir}/${pack}"
341                                 downloadExtraUrls "${pack}"
342                         )
343                 fi
344
345         )
346 }
347
348 downloadPackList () {
349         local download_dir
350         local name_list
351
352         download_dir="${1}"
353         name_list="${2}"
354
355         for name in ${name_list}
356         do
357                 if printNameList | inList "${name}"
358                 then
359                         downloadPack "${download_dir}" "${name}"
360                 else
361                         printError "unknown name: ${name}"
362                 fi
363         done
364 }
365
366 installPack () {
367         local download_dir
368         local install_dir
369         local name
370         local pack
371         local path
372         local game_file
373         local game_dir
374
375         download_dir="${1}"
376         install_dir="${2}"
377         name="${3}"
378
379         pack="${name}${pack_suffix}"
380
381         ${MKDIR_P} "${install_dir}/${games_dir}"
382
383         # Some per-game workaround for malformed gamepack
384         case "${name}" in
385                 'JediAcademy')
386                         pack="${pack}/Tools"
387                         ;;
388                 'Prey'|'Q3')
389                         pack="${pack}/tools"
390                         ;;
391                 'Wolf')
392                         pack="${pack}/bin"
393                         ;;
394         esac
395
396         # mkeditorpacks-based gamepack
397         if [ -d "${download_dir}/${pack}/build/netradiant" ]
398         then
399                 pack="${pack}/build/netradiant"
400         fi
401
402         path="${download_dir}/${pack}"
403
404         for game_file in "${path}/${games_dir}/"*'.game'
405         do
406                 if [ x"${game_file}" != x"${path}/"*'.game' ]
407                 then
408                         ${CP} "${game_file}" "${real_install_dir}/${games_dir}/"
409                 fi
410         done
411
412         for game_dir in "${path}/"*'.game'
413         do
414                 if [ x"${game_dir}" != x"${path}/"*'.game' ]
415                 then
416                         ${CP_R} "${game_dir}" "${real_install_dir}/"
417                 fi
418         done
419 }
420
421 installPackList () {
422         local download_dir
423         local install_dir
424         local name_list
425
426         download_dir="${1}"
427         install_dir="${2}"
428         name_list="${3}"
429
430         for name in ${name_list}
431         do
432                 if printNameList | inList "${name}"
433                 then
434                         installPack "${download_dir}" "${install_dir}" "${name}"
435                 else
436                         printError "unknown name: ${name}"
437                 fi
438         done
439 }
440
441 printError () {
442         printf 'ERROR: %s\n' "${1}" >&2
443         exit 1
444 }
445
446 printHelp () {
447         local tab
448         local prog_name
449
450         tab="$(printf '\t')"
451         prog_name="$(basename "$(readlink -f "${0}")")"
452
453         cat <<-EOF
454         Usage: ${prog_name} [OPTION] [SELECTION <ARGUMENTS>] [ACTION]
455
456         OPTIONS:
457         ${tab}-dd, --download-dir DIRNAME
458         ${tab}${tab}store downloaded games to DIRNAME (default: ${default_download_dir})
459
460         ${tab}-id, --install-dir DIRNAME
461         ${tab}${tab}store installed games to DIRNAME (default: ${default_install_dir})
462
463         SELECTIONS:
464         ${tab}-n, --name NAMES…
465         ${tab}${tab}select games by name (default: none)
466         ${tab}${tab}special keyword: all, none
467         ${tab}${tab}available games:
468         $(printNameList | sed -e 's/^/\t\t\t/')
469
470         ${tab}-l, --license LICENSES…
471         ${tab}${tab}select games by license (default: none)
472         ${tab}${tab}special keyword: free, all, none
473         ${tab}${tab}available licenses:
474         $(printLicenseList | sed -e 's/^/\t\t\t/')
475
476         ACTIONS:
477         ${tab}-ln, --list-names
478         ${tab}${tab}list all game names
479
480         ${tab}-ll, --list-licenses
481         ${tab}${tab}list all game licenses
482
483         ${tab}-ls, --list
484         ${tab}${tab}list selected games
485
486         ${tab}-d, --download
487         ${tab}${tab}download selected games
488
489         ${tab}-i, --install
490         ${tab}${tab}install selected games
491
492         ${tab}-h, --help
493         ${tab}${tab}print this help
494
495         Example:
496         ${tab}${prog_name} --license GPL BSD --download --install
497
498         EOF
499
500         exit
501 }
502
503 option_list=''
504
505 list_selected='false'
506 list_licenses='false'
507 list_names='false'
508
509 download_packs='false'
510 install_packs='false'
511
512 mkdir_download='false'
513 mkdir_install='false'
514
515 by_license='false'
516 by_name='false'
517
518 arg_type=''
519 selected_list=''
520 license_list=''
521 name_list=''
522 install_dir=''
523
524 while ! [ -z "${1}" ]
525 do
526
527         if printList "${option_list}" | inList "${1}"
528         then
529                 printError "option called more than once: ${1}"
530         fi
531
532         if echo "${@}" | tr ' ' '\n' | inList '--help'
533         then
534                 printHelp
535         elif echo "${@}" | tr ' ' '\n' | inList '-h'
536         then
537                 printHelp
538         fi
539
540         case "${1}" in
541                 '--list-licenses'|'-ll')
542                         arg_type=''
543                         list_licenses='true'
544                         option_list="${option_list} ${1}"
545                         ;;
546                 '--list-names'|'-ln')
547                         arg_type=''
548                         list_names='true'
549                         option_list="${option_list} ${1}"
550                         ;;
551                 '--list-selected'|'-ls')
552                         arg_type=''
553                         list_selected='true'
554                         option_list="${option_list} ${1}"
555                         ;;
556                 '--download'|'-d')
557                         arg_type=''
558                         download_packs='true'
559                         mkdir_download='true'
560                         option_list="${option_list} ${1}"
561                         ;;
562                 '--install'|'-i')
563                         arg_type=''
564                         install_packs='true'
565                         mkdir_download='true'
566                         mkdir_install='true'
567                         option_list="${option_list} ${1}"
568                         ;;
569                 '--license'|'-l')
570                         by_license='true'
571                         arg_type='pack-license'
572                         option_list="${option_list} ${1}"
573                         ;;
574                 '--name'|'-n')
575                         by_name='true'
576                         arg_type='pack-name'
577                         option_list="${option_list} ${1}"
578                         ;;
579                 '--download-dir'|'-dd')
580                         arg_type='download-dir'
581                         option_list="${option_list} ${1}"
582                         ;;
583                 '--install-dir'|'-id')
584                         arg_type='install-dir'
585                         option_list="${option_list} ${1}"
586                         ;;
587                 '-'*)
588                         printError "unknown option: ${1}"
589                         ;;
590                 *)
591                         case "${arg_type}" in
592                                 'pack-license')
593                                         license_list="${license_list} ${1}"
594                                         ;;
595                                 'pack-name')
596                                         name_list="${name_list} ${1}"
597                                         ;;
598                                 'download-dir')
599                                         if [ -z "${download_dir}" ]
600                                         then
601                                                 download_dir="${1}"
602                                         else
603                                                 printError "more than one download dir: ${1}"
604                                         fi
605                                         ;;
606                                 'install-dir')
607                                         if [ -z "${install_dir}" ]
608                                         then
609                                                 install_dir="${1}"
610                                         else
611                                                 printError "more than one install dir: ${1}"
612                                         fi
613                                         ;;
614                                 *)
615                                         printError "misplaced argument: ${1}"
616                                         ;;
617                         esac
618                         ;;
619         esac
620
621         shift
622 done
623
624 # compatibility with legacy Makefile
625 if [ "${DOWNLOAD_GAMEPACKS}" = 'yes' ]
626 then
627         ! [ -z "${DOWNLOADDIR}" ] && download_dir="${DOWNLOADDIR}"
628         ! [ -z "${INSTALLDIR}" ] && install_dir="${INSTALDIR}"
629         license_list='free'
630         by_license='true'
631         download_packs='true'
632         install_packs='true'
633 fi
634
635 if [ -z "${download_dir}" ]
636 then
637         download_dir="${default_download_dir}"
638 fi
639
640 if [ -z "${install_dir}" ]
641 then
642         install_dir="${default_install_dir}"
643 fi
644
645 if "${by_license}"
646 then
647         selected_list="${selected_list} $(printNameListByLicense "${license_list}")"
648 fi
649
650 if "${by_name}"
651 then
652         selected_list="${selected_list} $(printNameListByName "${name_list}")"
653 fi
654
655 selected_list="$(dedupeList "${selected_list}")"
656
657 if "${mkdir_download}"
658 then
659         ${MKDIR_P} "${download_dir}"
660         real_download_dir="$(readlink -f "${download_dir}")"
661 fi
662
663 if "${mkdir_install}"
664 then
665         ${MKDIR_P} "${install_dir}"
666         real_install_dir="$(readlink -f "${install_dir}")"
667 fi
668
669 if "${list_licenses}"
670 then
671         printLicenseList
672 fi
673
674 if "${list_names}"
675 then
676         printNameList
677 fi
678 if "${list_selected}"
679 then
680         printList "${selected_list}"
681 fi
682
683 if "${download_packs}"
684 then
685         downloadPackList "${real_download_dir}" "${selected_list}"
686 fi
687
688 if "${install_packs}"
689 then
690         installPackList "${real_download_dir}" "${real_install_dir}" "${selected_list}"
691 fi
692
693 #EOF