3 # get usage help this way:
4 # ./gamepack_manager -h
12 : "${MKDIR:=mkdir -v}"
13 : "${MKDIR_P:=mkdir -vp}"
17 : "${UNZIPPER:=unzip}"
21 default_download_dir='build/download'
22 default_install_dir='build'
27 free_license_list='BSD GPL'
31 #######################################################
33 # IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT #
35 # Use two whitespaces or more as column separator #
37 #######################################################
39 #######################################################
41 #######################################################
43 # Quake2World was renamed as Quetoo.
44 # JediAcademy and JediOutcast gamepacks are unusable.
45 # Other gamepacks have better version available.
47 # JediAcademy no proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/JAPack/branches/1.5/
48 # JediOutcast no proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/JK2Pack/trunk/
49 # Kingpin no unknown zip http://download.kingpin.info/kingpin/editing/maps/map_editors/NetRadiant/addon/Kingpinpack.zip
50 # Neverball no proprietary zip http://ingar.intranifty.net/files/netradiant/gamepacks/NeverballPack.zip
51 # OpenArena no unknown zip http://ingar.intranifty.net/files/netradiant/gamepacks/OpenArenaPack.zip
52 # Quake2World no GPL svn svn://jdolan.dyndns.org/quake2world/trunk/gtkradiant
53 # Quake3 no proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/Q3Pack/trunk/ 29
54 # Quake no proprietary zip http://ingar.intranifty.net/files/netradiant/gamepacks/QuakePack.zip
55 # Tremulous no proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/TremulousPack/branches/1.5/
56 # Tremulous no proprietary zip http://ingar.intranifty.net/files/netradiant/gamepacks/TremulousPack.zip
57 # Unvanquished no unknown zip http://ingar.intranifty.net/gtkradiant/files/gamepacks/UnvanquishedPack.zip
58 # Warfork no GPL zip https://cdn.discordapp.com/attachments/611741789237411850/659512520553267201/netradiant_warfork_gamepack.zip
59 # Warsow no GPL svn https://svn.bountysource.com/wswpack/trunk/netradiant/games/WarsowPack/
60 # Warsow no GPL zip http://ingar.intranifty.net/files/netradiant/gamepacks/WarsowPack.zip
62 #######################################################
64 #######################################################
66 AlienArena yes GPL svn https://svn.code.sf.net/p/alienarena-cc/code/trunk/tools/netradiant_gamepack/AlienArenaPack
67 DarkPlaces yes GPL svn svn://svn.icculus.org/gtkradiant-gamepacks/DarkPlacesPack/branches/1.5/
68 Doom3 yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/Doom3Pack/branches/1.5/
69 ET yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/ETPack/branches/1.5/
70 Heretic2 yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/Her2Pack/branches/1.5/
71 JediAcademy yes proprietary git https://gitlab.com/netradiant/gamepacks/jediacademy-mapeditor-support.git
72 JediOutcast yes proprietary git https://gitlab.com/netradiant/gamepacks/jedioutcast-mapeditor-support.git
73 Kingpin yes unknown git https://gitlab.com/netradiant/gamepacks/kingpin-mapeditor-support.git
74 Neverball yes proprietary git https://gitlab.com/netradiant/gamepacks/neverball-mapeditor-support.git
75 Nexuiz yes GPL gitdir git://git.icculus.org/divverent/nexuiz.git misc/netradiant-NexuizPack master
76 OpenArena yes GPL git https://github.com/NeonKnightOA/oagamepack.git
77 Osirion yes GPL zip http://ingar.intranifty.net/files/netradiant/gamepacks/OsirionPack.zip
78 Prey yes proprietary git https://gitlab.com/netradiant/gamepacks/prey-mapeditor-support.git
79 Q3Rally yes proprietary svn https://svn.code.sf.net/p/q3rallysa/code/tools/radiant-config/radiant15-netradiant/
80 Quake2 yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/Q2Pack/branches/1.5/
81 Quake3 yes proprietary git https://gitlab.com/netradiant/gamepacks/quake3-mapeditor-support.git
82 Quake4 yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/Q4Pack/branches/1.5/
83 QuakeLive yes proprietary git https://gitlab.com/netradiant/gamepacks/quakelive-mapeditor-support.git
84 Quake yes GPL zip http://ingar.intranifty.net/files/netradiant/gamepacks/Quake1Pack.zip
85 Quetoo yes GPL svn svn://svn.icculus.org/gtkradiant-gamepacks/QuetooPack/branches/1.5/
86 SmokinGuns yes unknown git https://github.com/smokin-guns/smokinguns-mapeditor-support.git
87 SoF2 yes unknown git https://gitlab.com/netradiant/gamepacks/sof2-mapeditor-support.git
88 STVEF yes unknown git https://gitlab.com/netradiant/gamepacks/stvef-mapeditor-support.git
89 Tremulous yes proprietary git https://gitlab.com/netradiant/gamepacks/tremulous-mapeditor-support.git
90 TurtleArena yes proprietary git https://github.com/Turtle-Arena/turtle-arena-radiant-pack.git
91 UFOAI yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/UFOAIPack/branches/1.5/
92 Unvanquished yes BSD git https://github.com/Unvanquished/unvanquished-mapeditor-support.git
93 UrbanTerror yes unknown git https://gitlab.com/netradiant/gamepacks/urbanterror-mapeditor-support.git
94 Warfork yes GPL git https://gitlab.com/netradiant/gamepacks/warfork-mapeditor-support.git
95 Warsow yes GPL git https://github.com/Warsow/NetRadiantPack.git
96 Wolf yes proprietary svn svn://svn.icculus.org/gtkradiant-gamepacks/WolfPack/branches/1.5/
97 WoP yes proprietary git https://github.com/PadWorld-Entertainment/wop-mapeditor-support.git
98 Wrath yes GPL git https://gitlab.com/netradiant/gamepacks/wrath-mapeditor-support.git
99 Xonotic yes GPL git https://gitlab.com/xonotic/netradiant-xonoticpack.git
100 ZEQ2Lite yes unknown git https://gitlab.com/netradiant/gamepacks/zeq2lite-mapeditor-support.git
104 if command -v gsed >/dev/null
107 elif sed --help >/dev/null 2>&1
111 printf 'ERROR: GNU sed is missing\n' >&2
117 if command -v grealpath >/dev/null
120 elif command -v realpath >/dev/null
123 elif command -v greadlink >/dev/null
125 # test greadlink first as greadlink has the feature on macos
126 # but readlink only has it on linux, note that it's probably
128 # note: (g)readlink requires the file to be create first
130 elif command -v readlink >/dev/null
132 # --help and -f options are GNU readlink things
133 if readlink --help >/dev/null 2>&1
137 if ! python -c "import os; print(os.path.realpath('${1}'))"
139 printf 'ERROR: GNU realpath or other way to compute real path of a file is missing\n' >&2
147 ${SED} -e 's/#.*//;s/[ \t][ \t][ \t]*/\t/g;s/^[ \t]*//;s/[ \t]*$//' \
152 [ "$(grep "^${1}$")" = "${1}" ]
173 printLicenseList () {
175 | awk '{ print $3 }' \
181 | awk '{ print $1 }' \
185 printNameListByLicense () {
186 local arg_license_list
190 arg_license_list="${1}"
193 for license in ${arg_license_list}
200 license_list="$(printLicenseList)"
204 license_list="${license_list} ${free_license_list}"
207 if printLicenseList | inList "${license}"
209 license_list="${license_list} ${license}"
211 printError "unknown license: ${license}"
217 license_list="$(dedupeList "${license_list}")"
219 for license in ${license_list}
222 | awk '$3 == "'"${license}"'"' \
227 printNameListByName () {
235 for name in ${argname_list}
242 name_list="$(printNameList)"
246 name_list="${name_list} validated"
249 if printNameList | inList "${name}"
251 name_list="${name_list} ${name}"
253 printError "unknown name: ${name}"
259 name_list="$(dedupeList "${name_list}")"
261 for name in ${name_list}
263 if [ "${name}" = 'validated' ]
266 | awk '$2 == "yes"' \
271 | awk '$1 == "'"${name}"'"' \
282 | awk '$1 == "'"${name}"'"'
292 printPackLine "${name}" \
293 | awk '{ print $'"${key}"' }'
298 if [ -f 'extra-urls.txt' ]
303 local extra_file="$(echo "${line}" | cut -f1 -d$'\t')"
304 local extra_url="$(echo "${line}" | cut -f2 -d$'\t')"
305 ${WGET} -O "${extra_file}" "${extra_url}" < /dev/null
306 done < 'extra-urls.txt'
324 validation="$(getValue "${name}" 2)"
325 license="$(getValue "${name}" 3)"
326 source_type="$(getValue "${name}" 4)"
327 source_url="$(getValue "${name}" 5)"
329 pack="${name}${pack_suffix}"
331 ${MKDIR_P} "${download_dir}"
337 ${ECHO} "Available pack: ${pack}"
338 ${ECHO} " License: ${license}"
339 ${ECHO} " Download via ${source_type} from ${source_url}"
342 if [ -d "${download_dir}/${pack}" ]
344 ${ECHO} "Updating ${name}…"
346 ${ECHO} "Downloading ${pack}…"
349 case "${source_type}" in
351 reference="$(getValue "${name}" 6)"
352 if [ -z "${reference}" ]
359 if [ -d "${pack}/.git" ]
366 ${SVN} update -r"${reference}" "${pack}"
369 ${SVN} checkout -r"${reference}" "${source_url}" "${pack}" \
370 || ${GIT} svn clone "${source_url}" "${pack}"
374 ${RM_R} 'zipdownload'
375 ${MKDIR} 'zipdownload'
378 ${WGET} "${source_url}"
379 ${UNZIPPER} './'*.zip
383 if [ -d 'zipdownload/games' ]
385 ${MV} 'zipdownload/'* "${pack}/"
387 ${MV} 'zipdownload/'*'/'* "${pack}/"
389 ${RM_R} 'zipdownload'
392 local subdir="$(getValue "${name}" 6)"
393 local branch="$(getValue "${name}" 7)"
395 ${GIT} archive --remote="${source_url}" --prefix="${pack}/" "${branch}":"${subdir}" \
406 ${GIT} clone "${source_url}" "${pack}"
422 downloadPackList () {
429 for name in ${name_list}
431 if printNameList | inList "${name}"
433 downloadPack "${download_dir}" "${name}"
435 printError "unknown name: ${name}"
453 pack="${name}${pack_suffix}"
455 ${MKDIR_P} "${install_dir}/${games_dir}"
457 # Some per-game workaround for malformed gamepack
464 # Game packs built with mkeditorpacks
465 if [ -d "${download_dir}/${pack}/build/netradiant" ]
467 pack="${pack}/build/netradiant"
468 elif [ -d "${download_dir}/${pack}/netradiant" ]
471 pack="${pack}/netradiant"
474 path="${download_dir}/${pack}"
476 for game_file in "${path}/${games_dir}/"*'.game'
478 if [ x"${game_file}" != x"${path}/"*'.game' ]
480 ${CP} "${game_file}" "${real_install_dir}/${games_dir}/"
484 for game_dir in "${path}/"*'.game'
486 if [ x"${game_dir}" != x"${path}/"*'.game' ]
488 ${CP_R} "${game_dir}" "${real_install_dir}/"
502 for name in ${name_list}
504 if printNameList | inList "${name}"
506 installPack "${download_dir}" "${install_dir}" "${name}"
508 printError "unknown name: ${name}"
514 printf 'ERROR: %s\n' "${1}" >&2
523 prog_name='gamepack-manager'
526 Usage: ${prog_name} [OPTION] [SELECTION <ARGUMENTS>] [ACTION]
529 ${tab}-dd, --download-dir DIRNAME
530 ${tab}${tab}store downloaded games to DIRNAME (default: ${default_download_dir})
532 ${tab}-id, --install-dir DIRNAME
533 ${tab}${tab}store installed games to DIRNAME (default: ${default_install_dir})
536 ${tab}-n, --name NAMES…
537 ${tab}${tab}select games by name (default: none)
538 ${tab}${tab}special keyword: validated, all, none
539 ${tab}${tab}available games:
540 $(printNameList | ${SED} -e 's/^/\t\t\t/')
542 ${tab}-l, --license LICENSES…
543 ${tab}${tab}select games by license (default: none)
544 ${tab}${tab}special keyword: free, all, none
545 ${tab}${tab}available licenses:
546 $(printLicenseList | ${SED} -e 's/^/\t\t\t/')
549 ${tab}-ln, --list-names
550 ${tab}${tab}list all game names
552 ${tab}-ll, --list-licenses
553 ${tab}${tab}list all game licenses
555 ${tab}-ls, --list-selected
556 ${tab}${tab}list selected games
559 ${tab}${tab}download selected games
562 ${tab}${tab}install selected games
565 ${tab}${tab}print this help
568 ${tab}${prog_name} --license GPL BSD --list-selected
569 ${tab}${prog_name} --license GPL BSD --download --install
571 ${tab}${prog_name} --name validated --list-selected
572 ${tab}${prog_name} --name validated --download --install
581 list_selected='false'
582 list_licenses='false'
585 download_packs='false'
586 install_packs='false'
588 mkdir_download='false'
589 mkdir_install='false'
600 while ! [ -z "${1}" ]
603 if printList "${option_list}" | inList "${1}"
605 printError "option called more than once: ${1}"
608 if echo "${@}" | tr ' ' '\n' | inList '--help'
611 elif echo "${@}" | tr ' ' '\n' | inList '-h'
617 '--list-names'|'-ln')
620 option_list="${option_list} ${1}"
622 '--list-licenses'|'-ll')
625 option_list="${option_list} ${1}"
627 '--list-selected'|'-ls')
630 option_list="${option_list} ${1}"
634 download_packs='true'
635 mkdir_download='true'
636 option_list="${option_list} ${1}"
641 mkdir_download='true'
643 option_list="${option_list} ${1}"
647 arg_type='pack-license'
648 option_list="${option_list} ${1}"
653 option_list="${option_list} ${1}"
655 '--download-dir'|'-dd')
656 arg_type='download-dir'
657 option_list="${option_list} ${1}"
659 '--install-dir'|'-id')
660 arg_type='install-dir'
661 option_list="${option_list} ${1}"
664 printError "unknown option: ${1}"
667 case "${arg_type}" in
669 name_list="${name_list} ${1}"
672 license_list="${license_list} ${1}"
675 if [ -z "${download_dir}" ]
679 printError "more than one download dir: ${1}"
683 if [ -z "${install_dir}" ]
687 printError "more than one install dir: ${1}"
691 printError "misplaced argument: ${1}"
700 # compatibility with legacy Makefile
701 if [ "${DOWNLOAD_GAMEPACKS}" = 'yes' ]
703 if ! [ -z "${DOWNLOADDIR}" ]
705 download_dir="${DOWNLOADDIR}"
708 if ! [ -z "${INSTALLDIR}" ]
710 install_dir="${INSTALLDIR}"
716 download_packs='true'
717 mkdir_download='true'
723 if [ -z "${download_dir}" ]
725 download_dir="${default_download_dir}"
728 if [ -z "${install_dir}" ]
730 install_dir="${default_install_dir}"
735 selected_list="${selected_list} $(printNameListByName "${name_list}")"
740 selected_list="${selected_list} $(printNameListByLicense "${license_list}")"
743 selected_list="$(dedupeList "${selected_list}")"
745 if "${mkdir_download}"
747 ${MKDIR_P} "${download_dir}"
748 real_download_dir="$(printRealPath "${download_dir}")"
751 if "${mkdir_install}"
753 ${MKDIR_P} "${install_dir}"
754 real_install_dir="$(printRealPath "${install_dir}")"
762 if "${list_licenses}"
767 if "${list_selected}"
769 printList "${selected_list}"
772 if "${download_packs}"
774 downloadPackList "${real_download_dir}" "${selected_list}"
777 if "${install_packs}"
779 installPackList "${real_download_dir}" "${real_install_dir}" "${selected_list}"