command_fastdl.sh 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. #!/bin/bash
  2. # LinuxGSM command_fastdl.sh module
  3. # Author: Daniel Gibbs
  4. # Contributors: https://linuxgsm.com/contrib
  5. # Website: https://linuxgsm.com
  6. # Description: Creates a Fastdl directory.
  7. commandname="FASTDL"
  8. commandaction="Fastdl"
  9. moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
  10. fn_firstcommand_set
  11. # Directories.
  12. if [ -z "${webdir}" ]; then
  13. webdir="${rootdir}/public_html"
  14. fi
  15. fastdldir="${webdir}/fastdl"
  16. addonsdir="${systemdir}/addons"
  17. # Server lua autorun dir, used to autorun lua on client connect to the server.
  18. luasvautorundir="${systemdir}/lua/autorun/server"
  19. luafastdlfile="lgsm_cl_force_fastdl.lua"
  20. luafastdlfullpath="${luasvautorundir}/${luafastdlfile}"
  21. # File lists.
  22. fastdlfilelist="${tmpdir}/fastdl_files.txt"
  23. fastdlduplicatelist="${tmpdir}/fastdl_files_duplicate.txt"
  24. fastdlnewrecord="${tmpdir}/fastdl_record.txt"
  25. fastdlrecord="${datadir}/${selfname}-fastdl.txt"
  26. fastdlclientlist="${tmpdir}/fastdl_files_client.txt"
  27. fastdlupdatelist="${tmpdir}/fastdl_files_to_update.txt"
  28. fastdlremovelist="${tmpdir}/fastdl_files_to_remove.txt"
  29. fastdlcompresslist="${tmpdir}/fastdl_files_to_compress.txt"
  30. fastdlmaxcompresssize="157286400"
  31. # Header
  32. fn_print_header
  33. fn_print_nl "More info: ${italic}https://docs.linuxgsm.com/commands/fastdl"
  34. fn_print_nl ""
  35. # Prompts user for Fastdl creation settings.
  36. fn_print_nl "${bold}${lightyellow}${commandaction} Setup"
  37. fn_messages_separator
  38. # Prompt for a full rebuild if directory was already here.
  39. fastdlrebuild="off"
  40. if [ -d "${fastdldir}" ]; then
  41. fn_print_info_nl "Fastdl directory already exists, only changed files will be updated."
  42. fn_print_nl "${fastdldir}"
  43. fn_print_nl ""
  44. if fn_prompt_yn "Rebuild Fastdl directory from scratch? This deletes everything in it." N; then
  45. fastdlrebuild="on"
  46. fn_script_log_info "Rebuild Fastdl directory from scratch: YES"
  47. else
  48. fn_script_log_info "Rebuild Fastdl directory from scratch: NO"
  49. fi
  50. fi
  51. # Garry's Mod Specific.
  52. if [ "${shortname}" == "gmod" ]; then
  53. # Prompt for download enforcer, which is using a .lua addfile resource generator.
  54. if fn_prompt_yn "Force clients to download files?" Y; then
  55. luaresource="on"
  56. fn_script_log_info "Force clients to download files: YES"
  57. else
  58. luaresource="off"
  59. fn_script_log_info "Force clients to download files: NO"
  60. fi
  61. fi
  62. # Clears any fastdl directory content.
  63. fn_clear_old_fastdl() {
  64. # Clearing old Fastdl.
  65. if [ -d "${fastdldir}" ]; then
  66. fn_print "clearing existing Fastdl directory ${fastdldir}"
  67. rm -rf "${fastdldir:?}"
  68. exitcode=$?
  69. if [ "${exitcode}" -ne 0 ]; then
  70. fn_print_fail_eol_nl
  71. fn_script_log_fail "Clearing existing Fastdl directory ${fastdldir}"
  72. core_exit.sh
  73. else
  74. fn_print_ok_eol_nl
  75. fn_script_log_pass "Clearing existing Fastdl directory ${fastdldir}"
  76. fi
  77. fi
  78. }
  79. fn_fastdl_dirs() {
  80. # Check and create directories.
  81. if [ ! -d "${webdir}" ]; then
  82. fn_print "creating web directory ${webdir}"
  83. mkdir -p "${webdir}"
  84. exitcode=$?
  85. if [ "${exitcode}" -ne 0 ]; then
  86. fn_print_fail_eol_nl
  87. fn_script_log_fail "Creating web directory ${webdir}"
  88. core_exit.sh
  89. else
  90. fn_print_ok_eol_nl
  91. fn_script_log_pass "Creating web directory ${webdir}"
  92. fi
  93. fi
  94. if [ ! -d "${fastdldir}" ]; then
  95. fn_print "creating fastdl directory ${fastdldir}"
  96. mkdir -p "${fastdldir}"
  97. exitcode=$?
  98. if [ "${exitcode}" -ne 0 ]; then
  99. fn_print_fail_eol_nl
  100. fn_script_log_fail "Creating fastdl directory ${fastdldir}"
  101. core_exit.sh
  102. else
  103. fn_print_ok_eol_nl
  104. fn_script_log_pass "Creating fastdl directory ${fastdldir}"
  105. fi
  106. fi
  107. }
  108. # Using this gist https://gist.github.com/agunnerson-ibm/efca449565a3e7356906
  109. fn_human_readable_file_size() {
  110. local abbrevs=(
  111. "1152921504606846976:ZB"
  112. "1125899906842624:EB"
  113. "1099511627776:TB"
  114. "1073741824:GB"
  115. "1048576:MB"
  116. "1024:KB"
  117. "1:bytes"
  118. )
  119. local bytes="${1}"
  120. local precision="${2}"
  121. if [[ "${bytes}" == "1" ]]; then
  122. fn_print_nl "1 byte"
  123. else
  124. for item in "${abbrevs[@]}"; do
  125. local factor="${item%:*}"
  126. local abbrev="${item#*:}"
  127. if [[ "${bytes}" -ge "${factor}" ]]; then
  128. size=$(bc -l <<< "${bytes} / ${factor}")
  129. printf "%.*f %s\n" "${precision}" "${size}" "${abbrev}"
  130. break
  131. fi
  132. done
  133. fi
  134. }
  135. # Sets the GoldSrc file types to include for the current directory.
  136. fn_fastdl_goldsrc_extensions() {
  137. fastdl_find_maxdepth=()
  138. if [ "${directory}" == "." ]; then
  139. allowed_extentions_array=("*.wad")
  140. fastdl_find_maxdepth=("-maxdepth" "1")
  141. elif [ "${directory}" == "maps" ]; then
  142. allowed_extentions_array=("*.bsp" "*.res" "*.txt")
  143. elif [ "${directory}" == "models" ]; then
  144. allowed_extentions_array=("*.mdl")
  145. elif [ "${directory}" == "sound" ]; then
  146. allowed_extentions_array=("*.wav")
  147. elif [ "${directory}" == "sprites" ]; then
  148. allowed_extentions_array=("*.spr" "*.txt")
  149. elif [ "${directory}" == "gfx" ]; then
  150. allowed_extentions_array=("*.tga" "*.bmp")
  151. elif [ "${directory}" == "overviews" ]; then
  152. allowed_extentions_array=("*.bmp" "*.tga" "*.txt")
  153. fi
  154. }
  155. # Sets the Source file types to include for the current directory.
  156. fn_fastdl_source_extensions() {
  157. fastdl_find_maxdepth=()
  158. if [ "${directory}" == "maps" ]; then
  159. allowed_extentions_array=("*.bsp" "*.ain" "*.nav" "*.jpg" "*.txt")
  160. elif [ "${directory}" == "materials" ]; then
  161. allowed_extentions_array=("*.vtf" "*.vmt" "*.vbf" "*.png" "*.svg")
  162. elif [ "${directory}" == "models" ]; then
  163. allowed_extentions_array=("*.vtx" "*.vvd" "*.mdl" "*.phy" "*.jpg" "*.png" "*.vmt" "*.vtf")
  164. elif [ "${directory}" == "particles" ]; then
  165. allowed_extentions_array=("*.pcf")
  166. elif [ "${directory}" == "sound" ]; then
  167. allowed_extentions_array=("*.wav" "*.mp3" "*.ogg")
  168. elif [ "${directory}" == "resource" ]; then
  169. allowed_extentions_array=("*")
  170. fi
  171. }
  172. # Adds the allowed files in a content directory to the file list.
  173. fn_fastdl_gather() {
  174. local basedir="${1}"
  175. local priority="${2}"
  176. local label="${directory}"
  177. if [ "${basedir}" != "${systemdir}" ]; then
  178. label="${basedir#"${systemdir}/"}/${directory}"
  179. fi
  180. for allowed_extention in "${allowed_extentions_array[@]}"; do
  181. fileswc=0
  182. tput sc
  183. while IFS=$'\t' read -r filesize filemtime fastdlfile; do
  184. ((fileswc++))
  185. tput rc
  186. tput el
  187. fn_print "gathering ${label} ${allowed_extention} : ${fileswc}"
  188. fastdlrelpath="${fastdlfile#"${basedir}/"}"
  189. printf '%s\t%s\t%s\t%s\t%s\n' "${priority}" "${fastdlrelpath#./}" "${filesize}" "${filemtime}" "${fastdlfile}" >> "${fastdlfilelist}"
  190. done < <(find "${basedir}/${directory}" "${fastdl_find_maxdepth[@]}" -type f -iname "${allowed_extention}" -printf '%s\t%T@\t%p\n')
  191. tput rc
  192. tput el
  193. fn_print "gathering ${label} ${allowed_extention} : ${fileswc}"
  194. if [ ${fileswc} != 0 ]; then
  195. fn_print_ok_eol_nl
  196. else
  197. fn_print_info_eol_nl
  198. fi
  199. done
  200. }
  201. # Adds Garry's Mod files to the file list.
  202. fn_fastdl_gather_gmod() {
  203. cd "${systemdir}" || exit
  204. allowed_extentions_array=("*.ain" "*.bsp" "*.mdl" "*.mp3" "*.ogg" "*.otf" "*.pcf" "*.phy" "*.png" "*.svg" "*.vtf" "*.vmt" "*.vtx" "*.vvd" "*.ttf" "*.wav")
  205. for allowed_extention in "${allowed_extentions_array[@]}"; do
  206. fileswc=0
  207. tput sc
  208. while IFS=$'\t' read -r filesize filemtime fastdlfile; do
  209. ((fileswc++))
  210. tput rc
  211. tput el
  212. fn_print "gathering ${allowed_extention} : ${fileswc}"
  213. fastdlrelpath="${fastdlfile#./}"
  214. priority="2"
  215. if [[ "${fastdlrelpath}" == addons/* ]]; then
  216. addonname="${fastdlrelpath#addons/}"
  217. addonname="${addonname%%/*}"
  218. if [ "addons/${addonname}" == "${fastdlrelpath}" ]; then
  219. continue
  220. fi
  221. priority="1:${addonname}"
  222. fastdlrelpath="${fastdlrelpath#addons/"${addonname}"/}"
  223. fi
  224. printf '%s\t%s\t%s\t%s\t%s\n' "${priority}" "${fastdlrelpath}" "${filesize}" "${filemtime}" "${systemdir}/${fastdlfile#./}" >> "${fastdlfilelist}"
  225. if [[ "${fastdlrelpath}" == lua/* ]]; then
  226. printf '%s\t%s\t%s\t%s\t%s\n' "0" "${fastdlrelpath#lua/}" "${filesize}" "${filemtime}" "${systemdir}/${fastdlfile#./}" >> "${fastdlfilelist}"
  227. fi
  228. done < <(find . -type f -iname "${allowed_extention}" -printf '%s\t%T@\t%p\n')
  229. if [ ${fileswc} != 0 ]; then
  230. fn_print_ok_eol_nl
  231. else
  232. fn_print_skip_eol_nl
  233. fi
  234. done
  235. }
  236. # Works out which files need to be copied, compressed or removed.
  237. fn_fastdl_plan() {
  238. LC_ALL=C sort -t $'\t' -k2,2 -k1,1 "${fastdlfilelist}" | awk -F '\t' -v dupes="${fastdlduplicatelist}" 'seen[$2]++ { print $5 " > " $2 > dupes; next } { print }' > "${fastdlfilelist}.sorted"
  239. mv -f "${fastdlfilelist}.sorted" "${fastdlfilelist}"
  240. if [ -f "${fastdlduplicatelist}" ]; then
  241. duplicatefiles=$(wc -l < "${fastdlduplicatelist}")
  242. while read -r duplicatefile; do
  243. fn_script_log_info "Skipping ${duplicatefile}, already provided by a higher priority path"
  244. done < "${fastdlduplicatelist}"
  245. fi
  246. declare -A fastdlrecordsource=()
  247. declare -A fastdlexpected=()
  248. if [ "${fastdlrebuild}" != "on" ] && [ -f "${fastdlrecord}" ] && [ "$(head -n 1 "${fastdlrecord}")" == "${fastdldir}" ]; then
  249. while IFS=$'\t' read -r fastdltarget recordsource; do
  250. [ -n "${fastdltarget}" ] && fastdlrecordsource["${fastdltarget}"]="${recordsource}"
  251. done < <(tail -n +2 "${fastdlrecord}")
  252. fi
  253. echo "${fastdldir}" > "${fastdlnewrecord}"
  254. read -ra fastdlexcludearray <<< "${fastdlexclude}"
  255. while IFS=$'\t' read -r priority fastdlrelpath filesize filemtime fastdlfile; do
  256. for excludepath in "${fastdlexcludearray[@]}"; do
  257. # shellcheck disable=SC2254
  258. case "${fastdlrelpath}" in
  259. ${excludepath#/}*)
  260. ((excludedfiles++))
  261. continue 2
  262. ;;
  263. esac
  264. done
  265. if [ "${engine}" == "goldsrc" ] || [ "${filesize}" -gt "${fastdlmaxcompresssize}" ]; then
  266. fastdlmode="copy"
  267. fastdltarget="${fastdlrelpath}"
  268. if [ "${engine}" != "goldsrc" ]; then
  269. ((largefiles++))
  270. fi
  271. else
  272. fastdlmode="compress"
  273. fastdltarget="${fastdlrelpath}.bz2"
  274. fi
  275. fastdlsource="${fastdlfile}"$'\t'"${filesize}"$'\t'"${filemtime}"
  276. fastdlexpected["${fastdltarget}"]="on"
  277. printf '%s\t%s\n' "${fastdltarget}" "${fastdlsource}" >> "${fastdlnewrecord}"
  278. echo "${fastdlrelpath}" >> "${fastdlclientlist}"
  279. if [ ! -f "${fastdldir}/${fastdltarget}" ] || [ "${fastdlrecordsource["${fastdltarget}"]}" != "${fastdlsource}" ]; then
  280. printf '%s\t%s\t%s\n' "${fastdlmode}" "${fastdlrelpath}" "${fastdlfile}" >> "${fastdlupdatelist}"
  281. ((updatefiles++))
  282. filesizetotal=$((filesizetotal + filesize))
  283. if [ "${fastdlmode}" == "compress" ]; then
  284. ((compressfiles++))
  285. fi
  286. else
  287. ((unchangedfiles++))
  288. fi
  289. done < "${fastdlfilelist}"
  290. for fastdltarget in "${!fastdlrecordsource[@]}"; do
  291. if [ -z "${fastdlexpected["${fastdltarget}"]}" ] && [ -f "${fastdldir}/${fastdltarget}" ]; then
  292. echo "${fastdltarget}" >> "${fastdlremovelist}"
  293. ((removefiles++))
  294. fi
  295. done
  296. if [ -d "${fastdldir}" ] && [ "${fastdlrebuild}" != "on" ]; then
  297. while read -r fastdltarget; do
  298. if [ -z "${fastdlexpected["${fastdltarget}"]}" ] && [ -z "${fastdlrecordsource["${fastdltarget}"]}" ]; then
  299. ((untrackedfiles++))
  300. fi
  301. done < <(find "${fastdldir}" -type f -printf '%P\n')
  302. fi
  303. }
  304. # Provides info about the fastdl directory content and prompts for confirmation.
  305. fn_fastdl_preview() {
  306. # Remove any file list.
  307. rm -f "${fastdlfilelist:?}" "${fastdlduplicatelist:?}" "${fastdlnewrecord:?}" "${fastdlclientlist:?}" "${fastdlupdatelist:?}" "${fastdlremovelist:?}" "${fastdlcompresslist:?}"
  308. touch "${fastdlclientlist}"
  309. totalfiles=0
  310. untrackedfiles=0
  311. duplicatefiles=0
  312. excludedfiles=0
  313. largefiles=0
  314. updatefiles=0
  315. compressfiles=0
  316. unchangedfiles=0
  317. removefiles=0
  318. filesizetotal=0
  319. fn_print_nl "analysing required files"
  320. fn_script_log_info "Analysing required files"
  321. # Garry's Mod
  322. if [ "${shortname}" == "gmod" ]; then
  323. fn_fastdl_gather_gmod
  324. # Source and GoldSrc engines
  325. else
  326. if [ "${engine}" == "goldsrc" ]; then
  327. fastdl_directories_array=("." "maps" "models" "sound" "sprites" "gfx" "overviews")
  328. else
  329. fastdl_directories_array=("maps" "materials" "models" "particles" "sound" "resource")
  330. fi
  331. fastdl_custom_array=()
  332. if [ "${engine}" == "source" ] && [ -d "${systemdir}/custom" ]; then
  333. while IFS= read -r -d '' customdir; do
  334. fastdl_custom_array+=("${customdir}")
  335. done < <(find "${systemdir}/custom" -mindepth 1 -maxdepth 1 -type d -print0 | LC_ALL=C sort -z)
  336. fi
  337. for directory in "${fastdl_directories_array[@]}"; do
  338. if [ "${engine}" == "goldsrc" ]; then
  339. fn_fastdl_goldsrc_extensions
  340. else
  341. fn_fastdl_source_extensions
  342. fi
  343. for customdir in "${fastdl_custom_array[@]}"; do
  344. if [ -d "${customdir}/${directory}" ]; then
  345. fn_fastdl_gather "${customdir}" "0:${customdir##*/}"
  346. fi
  347. done
  348. if [ -d "${systemdir}/${directory}" ]; then
  349. fn_fastdl_gather "${systemdir}" "1"
  350. fi
  351. done
  352. fi
  353. if [ -f "${fastdlfilelist}" ]; then
  354. fn_print_nl "calculating changes"
  355. fn_sleep_time_1
  356. totalfiles=$(wc -l < "${fastdlfilelist}")
  357. fn_fastdl_plan
  358. else
  359. fn_print_fail_eol_nl "generating file list"
  360. fn_script_log_fail "Generating file list."
  361. core_exit.sh
  362. fi
  363. echo -e "found ${totalfiles} files: ${unchangedfiles} unchanged, ${excludedfiles} excluded, ${duplicatefiles} duplicate"
  364. if [ "${updatefiles}" -gt 0 ]; then
  365. if [ "${engine}" == "source" ]; then
  366. echo -e "about to update ${updatefiles} files, ${compressfiles} to compress, total size $(fn_human_readable_file_size "${filesizetotal}" 0)"
  367. elif [ "${engine}" == "goldsrc" ]; then
  368. echo -e "about to copy ${updatefiles} files, total size $(fn_human_readable_file_size "${filesizetotal}" 0)"
  369. fi
  370. fi
  371. if [ "${largefiles}" -gt 0 ]; then
  372. echo -e "${largefiles} files over 150 MB will be copied without compression"
  373. fi
  374. if [ "${removefiles}" -gt 0 ]; then
  375. echo -e "about to remove ${removefiles} files no longer on the server"
  376. fi
  377. if [ "${untrackedfiles}" -gt 0 ]; then
  378. echo -e "${untrackedfiles} files in the Fastdl directory were not added by ${selfname} and will be left alone"
  379. fi
  380. if [ "${updatefiles}" -eq 0 ] && [ "${removefiles}" -eq 0 ]; then
  381. echo -e "Fastdl directory is up to date"
  382. fi
  383. fn_script_log_info "${totalfiles} files, ${updatefiles} to update, ${unchangedfiles} unchanged, ${excludedfiles} excluded, ${removefiles} to remove, total size $(fn_human_readable_file_size "${filesizetotal}" 0)"
  384. if ! fn_prompt_yn "Continue?" Y; then
  385. exitcode=0
  386. core_exit.sh
  387. fi
  388. }
  389. # Removes files from the fastdl directory that are no longer on the server.
  390. fn_fastdl_remove() {
  391. if [ -s "${fastdlremovelist}" ]; then
  392. fn_print "removing ${removefiles} files no longer on the server"
  393. while read -r fastdlstalefile; do
  394. rm -f "${fastdldir:?}/${fastdlstalefile}"
  395. exitcode=$?
  396. if [ "${exitcode}" -ne 0 ]; then
  397. fn_print_fail_eol_nl
  398. fn_script_log_fail "Removing ${fastdldir}/${fastdlstalefile}"
  399. core_exit.sh
  400. else
  401. fn_script_log_pass "Removing ${fastdldir}/${fastdlstalefile}"
  402. fi
  403. done < "${fastdlremovelist}"
  404. find "${fastdldir:?}" -mindepth 1 -type d -empty -delete
  405. fn_print_ok_eol_nl
  406. fi
  407. }
  408. # Copies new and changed files to the fastdl directory.
  409. fn_fastdl_copy() {
  410. if [ -s "${fastdlupdatelist}" ]; then
  411. fileswc=0
  412. tput sc
  413. while IFS=$'\t' read -r fastdlmode fastdlrelpath fastdlfile; do
  414. ((fileswc++))
  415. tput rc
  416. tput el
  417. fn_print "copying files : ${fileswc}/${updatefiles}"
  418. fastdltarget="${fastdldir}/${fastdlrelpath}"
  419. mkdir -p "${fastdltarget%/*}" && cp -p "${fastdlfile}" "${fastdltarget}"
  420. exitcode=$?
  421. if [ "${exitcode}" -ne 0 ]; then
  422. fn_print_fail_eol_nl
  423. fn_script_log_fail "Copying ${fastdlfile} > ${fastdltarget}"
  424. core_exit.sh
  425. else
  426. fn_script_log_pass "Copying ${fastdlfile} > ${fastdltarget}"
  427. fi
  428. if [ "${fastdlmode}" == "compress" ]; then
  429. printf '%s\0' "${fastdltarget}" >> "${fastdlcompresslist}"
  430. fi
  431. done < "${fastdlupdatelist}"
  432. fn_print_ok_eol_nl
  433. fi
  434. }
  435. # Builds the fastdl directory content.
  436. fn_fastdl_build() {
  437. # Copy all needed files for Fastdl.
  438. fn_print_nl "updating files in ${fastdldir}"
  439. fn_script_log_info "Updating files in ${fastdldir}"
  440. fn_fastdl_remove
  441. fn_fastdl_copy
  442. if [ "${shortname}" == "gmod" ]; then
  443. fn_fastdl_gmod_dl_enforcer
  444. fi
  445. }
  446. # Generate lua file that will force download any file into the Fastdl directory.
  447. fn_fastdl_gmod_dl_enforcer() {
  448. # Clear old lua file.
  449. if [ -f "${luafastdlfullpath}" ]; then
  450. fn_print "removing existing download enforcer: ${luafastdlfile}"
  451. rm -f "${luafastdlfullpath:?}"
  452. exitcode=$?
  453. if [ "${exitcode}" -ne 0 ]; then
  454. fn_print_fail_eol_nl
  455. fn_script_log_fail "Removing existing download enforcer ${luafastdlfullpath}"
  456. core_exit.sh
  457. else
  458. fn_print_ok_eol_nl
  459. fn_script_log_pass "Removing existing download enforcer ${luafastdlfullpath}"
  460. fi
  461. fi
  462. # Generate new one if user said yes.
  463. if [ "${luaresource}" == "on" ]; then
  464. fn_print "creating new download enforcer: ${luafastdlfile}"
  465. touch "${luafastdlfullpath}"
  466. # Read all filenames and put them into a lua file at the right path.
  467. while read -r line; do
  468. echo -e "resource.AddFile( \"${line}\" )" >> "${luafastdlfullpath}"
  469. done < "${fastdlclientlist}"
  470. exitcode=$?
  471. if [ "${exitcode}" -ne 0 ]; then
  472. fn_print_fail_eol_nl
  473. fn_script_log_fail "Creating new download enforcer ${luafastdlfullpath}"
  474. core_exit.sh
  475. else
  476. fn_print_ok_eol_nl
  477. fn_script_log_pass "Creating new download enforcer ${luafastdlfullpath}"
  478. fi
  479. fi
  480. }
  481. # Compresses Fastdl files using bzip2.
  482. fn_fastdl_bzip2() {
  483. if [ -s "${fastdlcompresslist}" ]; then
  484. fastdlthreads="$(nproc)"
  485. fn_print "compressing ${compressfiles} files using ${fastdlthreads} threads"
  486. xargs -0 -r -n 1 -P "${fastdlthreads}" bzip2 -f < "${fastdlcompresslist}"
  487. compressexitcode=$?
  488. while IFS=$'\t' read -r fastdlmode fastdlrelpath fastdlfile; do
  489. if [ "${fastdlmode}" == "compress" ]; then
  490. filetocompress="${fastdldir}/${fastdlrelpath}"
  491. if [ -f "${filetocompress}.bz2" ] && [ ! -f "${filetocompress}" ]; then
  492. fn_script_log_pass "Compressing ${filetocompress}"
  493. else
  494. fn_script_log_fail "Compressing ${filetocompress}"
  495. fi
  496. fi
  497. done < "${fastdlupdatelist}"
  498. if [ "${compressexitcode}" -ne 0 ]; then
  499. fn_print_fail_eol_nl
  500. fn_script_log_fail "Compressing files"
  501. exitcode=1
  502. core_exit.sh
  503. else
  504. fn_print_ok_eol_nl
  505. fn_script_log_pass "Compressing files"
  506. fi
  507. fi
  508. }
  509. # Saves the list of files written to the fastdl directory.
  510. fn_fastdl_record() {
  511. fn_print "saving Fastdl file record ${fastdlrecord}"
  512. mkdir -p "${datadir}" && mv -f "${fastdlnewrecord}" "${fastdlrecord}"
  513. exitcode=$?
  514. if [ "${exitcode}" -ne 0 ]; then
  515. fn_print_fail_eol_nl
  516. fn_script_log_fail "Saving Fastdl file record ${fastdlrecord}"
  517. core_exit.sh
  518. else
  519. fn_print_ok_eol_nl
  520. fn_script_log_pass "Saving Fastdl file record ${fastdlrecord}"
  521. fi
  522. }
  523. check.sh
  524. # Run functions.
  525. fn_fastdl_preview
  526. if [ "${fastdlrebuild}" == "on" ]; then
  527. fn_clear_old_fastdl
  528. fi
  529. fn_fastdl_dirs
  530. fn_fastdl_build
  531. if [ "${engine}" == "source" ]; then
  532. fn_fastdl_bzip2
  533. fi
  534. fn_fastdl_record
  535. rm -f "${fastdlfilelist:?}" "${fastdlduplicatelist:?}" "${fastdlnewrecord:?}" "${fastdlclientlist:?}" "${fastdlupdatelist:?}" "${fastdlremovelist:?}" "${fastdlcompresslist:?}"
  536. # Finished message.
  537. fn_print_nl "Fastdl files are located in:"
  538. fn_print_nl "${fastdldir}"
  539. fn_print_nl "Fastdl completed"
  540. fn_script_log_info "Fastdl completed"
  541. core_exit.sh