command_fastdl.sh 13 KB

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