command_fastdl.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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. # Check if bzip2 is installed.
  22. if [ ! "$(command -v bzip2 2> /dev/null)" ]; then
  23. fn_print_fail "bzip2 is not installed"
  24. fn_script_log_fail "bzip2 is not installed"
  25. core_exit.sh
  26. fi
  27. # Header
  28. fn_print_header
  29. fn_print_nl "More info: ${italic}https://docs.linuxgsm.com/commands/fastdl"
  30. fn_print_nl ""
  31. # Prompts user for Fastdl creation settings.
  32. fn_print_nl "${bold}${lightyellow}${commandaction} Setup"
  33. fn_messages_separator
  34. # Prompt for clearing old files if directory was already here.
  35. if [ -d "${fastdldir}" ]; then
  36. fn_print_warning_nl "Fastdl directory already exists."
  37. fn_print_nl "${fastdldir}"
  38. fn_print_nl ""
  39. if fn_prompt_yn "Overwrite existing directory?" Y; then
  40. fn_script_log_info "Overwrite existing directory: YES"
  41. else
  42. core_exit.sh
  43. fi
  44. fi
  45. # Garry's Mod Specific.
  46. if [ "${shortname}" == "gmod" ]; then
  47. # Prompt for download enforcer, which is using a .lua addfile resource generator.
  48. if fn_prompt_yn "Force clients to download files?" Y; then
  49. luaresource="on"
  50. fn_script_log_info "Force clients to download files: YES"
  51. else
  52. luaresource="off"
  53. fn_script_log_info "Force clients to download filesr: NO"
  54. fi
  55. fi
  56. # Clears any fastdl directory content.
  57. fn_clear_old_fastdl() {
  58. # Clearing old Fastdl.
  59. if [ -d "${fastdldir}" ]; then
  60. fn_print "clearing existing Fastdl directory ${fastdldir}"
  61. rm -rf "${fastdldir:?}"
  62. exitcode=$?
  63. if [ "${exitcode}" -ne 0 ]; then
  64. fn_print_fail_eol_nl
  65. fn_script_log_fail "Clearing existing Fastdl directory ${fastdldir}"
  66. core_exit.sh
  67. else
  68. fn_print_ok_eol_nl
  69. fn_script_log_pass "Clearing existing Fastdl directory ${fastdldir}"
  70. fi
  71. fi
  72. }
  73. fn_fastdl_dirs() {
  74. # Check and create directories.
  75. if [ ! -d "${webdir}" ]; then
  76. fn_print "creating web directory ${webdir}"
  77. mkdir -p "${webdir}"
  78. exitcode=$?
  79. if [ "${exitcode}" -ne 0 ]; then
  80. fn_print_fail_eol_nl
  81. fn_script_log_fail "Creating web directory ${webdir}"
  82. core_exit.sh
  83. else
  84. fn_print_ok_eol_nl
  85. fn_script_log_pass "Creating web directory ${webdir}"
  86. fi
  87. fi
  88. if [ ! -d "${fastdldir}" ]; then
  89. fn_print "creating fastdl directory ${fastdldir}"
  90. mkdir -p "${fastdldir}"
  91. exitcode=$?
  92. if [ "${exitcode}" -ne 0 ]; then
  93. fn_print_fail_eol_nl
  94. fn_script_log_fail "Creating fastdl directory ${fastdldir}"
  95. core_exit.sh
  96. else
  97. fn_print_ok_eol_nl
  98. fn_script_log_pass "Creating fastdl directory ${fastdldir}"
  99. fi
  100. fi
  101. }
  102. # Using this gist https://gist.github.com/agunnerson-ibm/efca449565a3e7356906
  103. fn_human_readable_file_size() {
  104. local abbrevs=(
  105. $((1 << 60)):ZB
  106. $((1 << 50)):EB
  107. $((1 << 40)):TB
  108. $((1 << 30)):GB
  109. $((1 << 20)):MB
  110. $((1 << 10)):KB
  111. $((1)):bytes
  112. )
  113. local bytes="${1}"
  114. local precision="${2}"
  115. if [[ "${bytes}" == "1" ]]; then
  116. fn_print_nl "1 byte"
  117. else
  118. for item in "${abbrevs[@]}"; do
  119. local factor="${item%:*}"
  120. local abbrev="${item#*:}"
  121. if [[ "${bytes}" -ge "${factor}" ]]; then
  122. size=$(bc -l <<< "${bytes} / ${factor}")
  123. printf "%.*f %s\n" "${precision}" "${size}" "${abbrev}"
  124. break
  125. fi
  126. done
  127. fi
  128. }
  129. # Provides info about the fastdl directory content and prompts for confirmation.
  130. fn_fastdl_preview() {
  131. # Remove any file list.
  132. if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then
  133. rm -f "${tmpdir:?}/fastdl_files_to_compress.txt"
  134. fi
  135. fn_print_nl "analysing required files"
  136. fn_script_log_info "Analysing required files"
  137. # Garry's Mod
  138. if [ "${shortname}" == "gmod" ]; then
  139. cd "${systemdir}" || exit
  140. allowed_extentions_array=("*.ain" "*.bsp" "*.mdl" "*.mp3" "*.ogg" "*.otf" "*.pcf" "*.phy" "*.png" "*.svg" "*.vtf" "*.vmt" "*.vtx" "*.vvd" "*.ttf" "*.wav")
  141. for allowed_extention in "${allowed_extentions_array[@]}"; do
  142. fileswc=0
  143. tput sc
  144. while read -r ext; do
  145. ((fileswc++))
  146. tput rc
  147. tput el
  148. fn_print "gathering ${allowed_extention} : ${fileswc}"
  149. echo -e "${ext}" >> "${tmpdir}/fastdl_files_to_compress.txt"
  150. done < <(find . -type f -iname "${allowed_extention}")
  151. if [ ${fileswc} != 0 ]; then
  152. fn_print_ok_eol_nl
  153. else
  154. fn_print_skip_eol_nl
  155. fi
  156. done
  157. # Source engine
  158. else
  159. fastdl_directories_array=("maps" "materials" "models" "particles" "sound" "resources")
  160. for directory in "${fastdl_directories_array[@]}"; do
  161. if [ -d "${systemdir}/${directory}" ]; then
  162. if [ "${directory}" == "maps" ]; then
  163. local allowed_extentions_array=("*.bsp" "*.ain" "*.nav" "*.jpg" "*.txt")
  164. elif [ "${directory}" == "materials" ]; then
  165. local allowed_extentions_array=("*.vtf" "*.vmt" "*.vbf" "*.png" "*.svg")
  166. elif [ "${directory}" == "models" ]; then
  167. local allowed_extentions_array=("*.vtx" "*.vvd" "*.mdl" "*.phy" "*.jpg" "*.png" "*.vmt" "*.vtf")
  168. elif [ "${directory}" == "particles" ]; then
  169. local allowed_extentions_array=("*.pcf")
  170. elif [ "${directory}" == "sound" ]; then
  171. local allowed_extentions_array=("*.wav" "*.mp3" "*.ogg")
  172. fi
  173. for allowed_extention in "${allowed_extentions_array[@]}"; do
  174. fileswc=0
  175. tput sc
  176. while read -r ext; do
  177. ((fileswc++))
  178. tput rc
  179. tput el
  180. fn_print "gathering ${directory} ${allowed_extention} : ${fileswc}"
  181. echo -e "${ext}" >> "${tmpdir}/fastdl_files_to_compress.txt"
  182. done < <(find "${systemdir}/${directory}" -type f -iname "${allowed_extention}")
  183. tput rc
  184. tput el
  185. fn_print "gathering ${directory} ${allowed_extention} : ${fileswc}"
  186. if [ ${fileswc} != 0 ]; then
  187. fn_print_ok_eol_nl
  188. else
  189. fn_print_info_eol_nl
  190. fi
  191. done
  192. fi
  193. done
  194. fi
  195. if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then
  196. fn_print_nl "calculating total file size"
  197. fn_sleep_time_1
  198. totalfiles=$(wc -l < "${tmpdir}/fastdl_files_to_compress.txt")
  199. # Calculates total file size.
  200. while read -r dufile; do
  201. filesize=$(stat -c %s "${dufile}")
  202. filesizetotal=$((filesizetotal + filesize))
  203. exitcode=$?
  204. if [ "${exitcode}" -ne 0 ]; then
  205. fn_print_fail_eol_nl
  206. fn_script_log_fail "Calculating total file size"
  207. core_exit.sh
  208. fi
  209. done < "${tmpdir}/fastdl_files_to_compress.txt"
  210. else
  211. fn_print_fail_eol_nl "generating file list"
  212. fn_script_log_fail "Generating file list."
  213. core_exit.sh
  214. fi
  215. fn_print_nl "about to compress ${totalfiles} files, total size $(fn_human_readable_file_size "${filesizetotal}" 0)"
  216. fn_script_log_info "${totalfiles} files, total size $(fn_human_readable_file_size "${filesizetotal}" 0)"
  217. rm -f "${tmpdir:?}/fastdl_files_to_compress.txt"
  218. if ! fn_prompt_yn "Continue?" Y; then
  219. fn_script_log "User exited"
  220. core_exit.sh
  221. fi
  222. }
  223. # Builds Garry's Mod fastdl directory content.
  224. fn_fastdl_gmod() {
  225. cd "${systemdir}" || exit
  226. for allowed_extention in "${allowed_extentions_array[@]}"; do
  227. fileswc=0
  228. tput sc
  229. while read -r fastdlfile; do
  230. ((fileswc++))
  231. tput rc
  232. tput el
  233. fn_print "copying ${allowed_extention} : ${fileswc}"
  234. cp --parents "${fastdlfile}" "${fastdldir}"
  235. exitcode=$?
  236. if [ "${exitcode}" -ne 0 ]; then
  237. fn_print_fail_eol_nl
  238. fn_script_log_fail "Copying ${fastdlfile} > ${fastdldir}"
  239. core_exit.sh
  240. else
  241. fn_script_log_pass "Copying ${fastdlfile} > ${fastdldir}"
  242. fi
  243. done < <(find . -type f -iname "${allowed_extention}")
  244. if [ ${fileswc} != 0 ]; then
  245. fn_print_ok_eol_nl
  246. fi
  247. done
  248. # Correct addons directory structure for Fastdl.
  249. if [ -d "${fastdldir}/addons" ]; then
  250. fn_print "updating addons file structure..."
  251. cp -Rf "${fastdldir}"/addons/*/* "${fastdldir}"
  252. exitcode=$?
  253. if [ "${exitcode}" -ne 0 ]; then
  254. fn_print_fail_eol_nl
  255. fn_script_log_fail "Updating addons file structure"
  256. core_exit.sh
  257. else
  258. fn_print_ok_eol_nl
  259. fn_script_log_pass "Updating addons file structure"
  260. fi
  261. # Clear addons directory in fastdl.
  262. fn_print "clearing addons dir from fastdl dir..."
  263. fn_sleep_time_1
  264. rm -rf "${fastdldir:?}/addons"
  265. exitcode=$?
  266. if [ "${exitcode}" -ne 0 ]; then
  267. fn_print_fail_eol_nl
  268. fn_script_log_fail "Clearing addons dir from fastdl dir"
  269. core_exit.sh
  270. else
  271. fn_print_ok_eol_nl
  272. fn_script_log_pass "Clearing addons dir from fastdl dir"
  273. fi
  274. fi
  275. # Correct content that may be into a lua directory by mistake like some darkrpmodification addons.
  276. if [ -d "${fastdldir}/lua" ]; then
  277. fn_print "correcting DarkRP files..."
  278. fn_sleep_time_1
  279. cp -Rf "${fastdldir}/lua/"* "${fastdldir}"
  280. exitcode=$?
  281. if [ "${exitcode}" -ne 0 ]; then
  282. fn_print_fail_eol_nl
  283. fn_script_log_fail "Correcting DarkRP files"
  284. core_exit.sh
  285. else
  286. fn_print_ok_eol_nl
  287. fn_script_log_pass "Correcting DarkRP files"
  288. fi
  289. fi
  290. if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then
  291. totalfiles=$(wc -l < "${tmpdir}/fastdl_files_to_compress.txt")
  292. # Calculates total file size.
  293. while read -r dufile; do
  294. filesize=$(du -b "${dufile}" | awk '{ print $1 }')
  295. filesizetotal=$((filesizetotal + filesize))
  296. done < "${tmpdir}/fastdl_files_to_compress.txt"
  297. fi
  298. }
  299. fn_fastdl_source() {
  300. for directory in "${fastdl_directories_array[@]}"; do
  301. if [ -d "${systemdir}/${directory}" ]; then
  302. if [ "${directory}" == "maps" ]; then
  303. local allowed_extentions_array=("*.bsp" "*.ain" "*.nav" "*.jpg" "*.txt")
  304. elif [ "${directory}" == "materials" ]; then
  305. local allowed_extentions_array=("*.vtf" "*.vmt" "*.vbf" "*.png" "*.svg")
  306. elif [ "${directory}" == "models" ]; then
  307. local allowed_extentions_array=("*.vtx" "*.vvd" "*.mdl" "*.phy" "*.jpg" "*.png")
  308. elif [ "${directory}" == "particles" ]; then
  309. local allowed_extentions_array=("*.pcf")
  310. elif [ "${directory}" == "sound" ]; then
  311. local allowed_extentions_array=("*.wav" "*.mp3" "*.ogg")
  312. fi
  313. for allowed_extention in "${allowed_extentions_array[@]}"; do
  314. fileswc=0
  315. tput sc
  316. while read -r fastdlfile; do
  317. ((fileswc++))
  318. tput rc
  319. tput el
  320. fn_print "copying ${directory} ${allowed_extention} : ${fileswc}"
  321. fn_sleep_time
  322. # get relative path of file in the dir
  323. tmprelfilepath="${fastdlfile#"${systemdir}/"}"
  324. copytodir="${tmprelfilepath%/*}"
  325. # create relative path for fastdl
  326. if [ ! -d "${fastdldir}/${copytodir}" ]; then
  327. mkdir -p "${fastdldir}/${copytodir}"
  328. fi
  329. cp "${fastdlfile}" "${fastdldir}/${copytodir}"
  330. exitcode=$?
  331. if [ "${exitcode}" -ne 0 ]; then
  332. fn_print_fail_eol_nl
  333. fn_script_log_fail "Copying ${fastdlfile} > ${fastdldir}/${copytodir}"
  334. core_exit.sh
  335. else
  336. fn_script_log_pass "Copying ${fastdlfile} > ${fastdldir}/${copytodir}"
  337. fi
  338. done < <(find "${systemdir}/${directory}" -type f -iname "${allowed_extention}")
  339. if [ ${fileswc} != 0 ]; then
  340. fn_print_ok_eol_nl
  341. fi
  342. done
  343. fi
  344. done
  345. }
  346. # Builds the fastdl directory content.
  347. fn_fastdl_build() {
  348. # Copy all needed files for Fastdl.
  349. fn_print_nl "copying files to ${fastdldir}"
  350. fn_script_log_info "Copying files to ${fastdldir}"
  351. if [ "${shortname}" == "gmod" ]; then
  352. fn_fastdl_gmod
  353. fn_fastdl_gmod_dl_enforcer
  354. else
  355. fn_fastdl_source
  356. fi
  357. }
  358. # Generate lua file that will force download any file into the Fastdl directory.
  359. fn_fastdl_gmod_dl_enforcer() {
  360. # Clear old lua file.
  361. if [ -f "${luafastdlfullpath}" ]; then
  362. fn_print "removing existing download enforcer: ${luafastdlfile}"
  363. rm -f "${luafastdlfullpath:?}"
  364. exitcode=$?
  365. if [ "${exitcode}" -ne 0 ]; then
  366. fn_print_fail_eol_nl
  367. fn_script_log_fail "Removing existing download enforcer ${luafastdlfullpath}"
  368. core_exit.sh
  369. else
  370. fn_print_ok_eol_nl
  371. fn_script_log_pass "Removing existing download enforcer ${luafastdlfullpath}"
  372. fi
  373. fi
  374. # Generate new one if user said yes.
  375. if [ "${luaresource}" == "on" ]; then
  376. fn_print "creating new download enforcer: ${luafastdlfile}"
  377. touch "${luafastdlfullpath}"
  378. # Read all filenames and put them into a lua file at the right path.
  379. while read -r line; do
  380. echo -e "resource.AddFile( \"${line}\" )" >> "${luafastdlfullpath}"
  381. done < <(find "${fastdldir:?}" \( -type f ! -name "*.bz2" \) -printf '%P\n')
  382. exitcode=$?
  383. if [ "${exitcode}" -ne 0 ]; then
  384. fn_print_fail_eol_nl
  385. fn_script_log_fail "Creating new download enforcer ${luafastdlfullpath}"
  386. core_exit.sh
  387. else
  388. fn_print_ok_eol_nl
  389. fn_script_log_pass "Creating new download enforcer ${luafastdlfullpath}"
  390. fi
  391. fi
  392. }
  393. # Compresses Fastdl files using bzip2.
  394. fn_fastdl_bzip2() {
  395. while read -r filetocompress; do
  396. fn_print "compressing ${filetocompress}"
  397. bzip2 -f "${filetocompress}"
  398. exitcode=$?
  399. if [ "${exitcode}" -ne 0 ]; then
  400. fn_print_fail_eol_nl
  401. fn_script_log_fail "Compressing ${filetocompress}"
  402. core_exit.sh
  403. else
  404. fn_print_ok_eol_nl
  405. fn_script_log_pass "Compressing ${filetocompress}"
  406. fi
  407. done < <(find "${fastdldir:?}" \( -type f ! -name "*.bz2" \))
  408. }
  409. check.sh
  410. # Run functions.
  411. fn_fastdl_preview
  412. fn_clear_old_fastdl
  413. fn_fastdl_dirs
  414. fn_fastdl_build
  415. fn_fastdl_bzip2
  416. # Finished message.
  417. fn_print_nl "Fastdl files are located in:"
  418. fn_print_nl "${fastdldir}"
  419. fn_print_nl "Fastdl completed"
  420. fn_script_log_info "Fastdl completed"
  421. core_exit.sh