command_fastdl.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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. webdir="${rootdir}/public_html"
  13. fastdldir="${webdir}/fastdl"
  14. addonsdir="${systemdir}/addons"
  15. # Server lua autorun dir, used to autorun lua on client connect to the server
  16. luasvautorundir="${systemdir}/lua/autorun/server"
  17. luafastdlfile="lgsm_cl_force_fastdl.lua"
  18. luafastdlfullpath="${luasvautorundir}/${luafastdlfile}"
  19. fn_check_bzip2(){
  20. # Returns true if not installed
  21. if [ -z "$(command -v bzip2)" ]; then
  22. bzip2installed="0"
  23. fn_print_info "bzip2 is not installed! Install it to enable file compression"
  24. fn_script_log_info "bzip2 is not installed. Install it to enable file compression."
  25. fn_script_log_info "https://github.com/GameServerManagers/LinuxGSM/wiki/FastDL#bzip2-compression"
  26. echo -en "\n"
  27. sleep 1
  28. echo " * https://github.com/GameServerManagers/LinuxGSM/wiki/FastDL#bzip2-compression"
  29. sleep 2
  30. echo ""
  31. else
  32. bzip2installed="1"
  33. fi
  34. }
  35. # Prompts user for FastDL creation settings
  36. fn_fastdl_config(){
  37. echo "FastDL setup"
  38. echo "================================="
  39. # Prompt for clearing old files if directory was already here
  40. if [ -d "${fastdldir}" ]; then
  41. fn_print_warning_nl "FastDL directory already exists."
  42. echo "${fastdldir}"
  43. echo ""
  44. if fn_prompt_yn "Overwrite existing directory?" Y; then
  45. clearoldfastdl="on"
  46. else
  47. clearoldfastdl="off"
  48. fi
  49. fi
  50. # Garry's Mod Specific
  51. if [ "${gamename}" == "Garry's Mod" ]; then
  52. # Prompt to clear addons dir from fastdl, can use unnecessary space or be required depending on addon's file structures
  53. fn_print_dots
  54. if fn_prompt_yn "Clear addons dir from fastdl dir?" Y; then
  55. cleargmodaddons="on";
  56. else
  57. cleargmodaddons="off";
  58. fi
  59. # Prompt for download enforcer, which is using a .lua addfile resource generator
  60. fn_print_dots
  61. if fn_prompt_yn "Use client download enforcer?" Y; then
  62. luaressource="on"
  63. else
  64. luaressource="off"
  65. fi
  66. fi
  67. }
  68. fn_fastdl_dirs(){
  69. # Check and create directories
  70. if [ ! -d "${modsdir}" ];then
  71. echo -en "creating web directory ${webdir}..."
  72. mkdir -p "${webdir}"
  73. exitcode=$?
  74. if [ ${exitcode} -ne 0 ]; then
  75. fn_print_fail_eol_nl
  76. fn_script_log_fatal "creating web directory ${webdir}..."
  77. core_exit.sh
  78. else
  79. fn_print_ok_eol_nl
  80. fn_script_log_pass "creating web directory ${webdir}..."
  81. fi
  82. sleep 0.5
  83. fi
  84. if [ ! -d "${fastdldir}" ];then
  85. echo -en "creating fastdl directory ${fastdldir}..."
  86. mkdir -p "${fastdldir}"
  87. exitcode=$?
  88. if [ ${exitcode} -ne 0 ]; then
  89. fn_print_fail_eol_nl
  90. fn_script_log_fatal "creating fastdl directory ${fastdldir}..."
  91. core_exit.sh
  92. else
  93. fn_print_ok_eol_nl
  94. fn_script_log_pass "creating fastdl directory ${fastdldir}..."
  95. fi
  96. sleep 0.5
  97. fi
  98. }
  99. fn_clear_old_fastdl(){
  100. # Clearing old FastDL if user answered yes
  101. if [ ! -d "${modsdir}" ];then
  102. echo -en "clearing existing FastDL directory ${fastdldir}..."
  103. rm -R "${fastdldir:?}"/*
  104. exitcode=$?
  105. if [ ${exitcode} -ne 0 ]; then
  106. fn_print_fail_eol_nl
  107. fn_script_log_fatal "clearing existing FastDL directory ${fastdldir}..."
  108. core_exit.sh
  109. else
  110. fn_print_ok_eol_nl
  111. fn_script_log_pass "clearing existing FastDL directory ${fastdldir}..."
  112. fi
  113. sleep 0.5
  114. fi
  115. }
  116. fn_fastdl_gmod(){
  117. # Copy all needed files for FastDL
  118. echo ""
  119. fn_print_dots "Starting gathering all needed files"
  120. fn_script_log "Starting gathering all needed files"
  121. sleep 1
  122. echo -en "\n"
  123. # No choice to cd to the directory, as find can't then display relative directory
  124. cd "${systemdir}" || exit
  125. # Map Files
  126. fn_print_dots "Copying map files..."
  127. fn_script_log "Copying map files"
  128. sleep 0.5
  129. find . -name '*.bsp' | cpio --quiet -updm "${fastdldir}"
  130. find . -name '*.ain' | cpio --quiet -updm "${fastdldir}"
  131. fn_print_ok "Map files copied"
  132. sleep 0.5
  133. echo -en "\n"
  134. # Materials
  135. fn_print_dots "Copying materials..."
  136. fn_script_log "Copying materials"
  137. sleep 0.5
  138. find . -name '*.vtf' | cpio --quiet -updm "${fastdldir}"
  139. find . -name '*.vmt' | cpio --quiet -updm "${fastdldir}"
  140. fn_print_ok "Materials copied"
  141. sleep 0.5
  142. echo -en "\n"
  143. # Models
  144. fn_print_dots "Copying models..."
  145. fn_script_log "Copying models"
  146. sleep 1
  147. find . -name '*.vtx' | cpio --quiet -updm "${fastdldir}"
  148. find . -name '*.vvd' | cpio --quiet -updm "${fastdldir}"
  149. find . -name '*.mdl' | cpio --quiet -updm "${fastdldir}"
  150. find . -name '*.phy' | cpio --quiet -updm "${fastdldir}"
  151. fn_print_ok "Models copied"
  152. sleep 0.5
  153. echo -en "\n"
  154. # Particles
  155. fn_print_dots "Copying particles..."
  156. fn_script_log "Copying particles"
  157. sleep 0.5
  158. find . -name '*.pcf' | cpio --quiet -updm "${fastdldir}"
  159. fn_print_ok "Particles copied"
  160. sleep 0.5
  161. echo -en "\n"
  162. # Sounds
  163. fn_print_dots "Copying sounds..."
  164. fn_script_log "Copying sounds"
  165. sleep 0.5
  166. find . -name '*.wav' | cpio --quiet -updm "${fastdldir}"
  167. find . -name '*.mp3' | cpio --quiet -updm "${fastdldir}"
  168. find . -name '*.ogg' | cpio --quiet -updm "${fastdldir}"
  169. fn_print_ok "Sounds copied"
  170. sleep 0.5
  171. echo -en "\n"
  172. # Resources (mostly fonts)
  173. fn_print_dots "Copying fonts and png..."
  174. fn_script_log "Copying fonts and png"
  175. sleep 1
  176. find . -name '*.otf' | cpio --quiet -updm "${fastdldir}"
  177. find . -name '*.ttf' | cpio --quiet -updm "${fastdldir}"
  178. find . -name '*.png' | cpio --quiet -updm "${fastdldir}"
  179. fn_print_ok "Fonts and png copied"
  180. sleep 0.5
  181. echo -en "\n"
  182. # Going back to rootdir in order to prevent mistakes
  183. cd "${rootdir}"
  184. # Correct addons directory structure for FastDL
  185. if [ -d "${fastdldir}/addons" ]; then
  186. fn_print_info "Adjusting addons' file structure"
  187. fn_script_log "Adjusting addons' file structure"
  188. sleep 1
  189. cp -Rf "${fastdldir}"/addons/*/* "${fastdldir}"
  190. fn_print_ok "Adjusted addons' file structure"
  191. sleep 1
  192. echo -en "\n"
  193. # Clear addons directory in fastdl
  194. if [ "${cleargmodaddons}" == "on" ]; then
  195. fn_print_info "Clearing addons dir from fastdl dir"
  196. fn_script_log "Clearing addons dir from fastdl dir"
  197. sleep 1
  198. rm -R "${fastdldir:?}/addons"
  199. fn_print_ok "Cleared addons dir from fastdl dir"
  200. sleep 1
  201. echo -en "\n"
  202. fi
  203. fi
  204. # Correct content that may be into a lua directory by mistake like some darkrpmodification addons
  205. if [ -d "${fastdldir}/lua" ]; then
  206. fn_print_dots "Typical DarkRP files detected, fixing"
  207. sleep 2
  208. cp -Rf "${fastdldir}/lua/"* "${fastdldir}"
  209. fn_print_ok "Stupid DarkRP file structure fixed"
  210. sleep 2
  211. echo -en "\n"
  212. fi
  213. }
  214. # Using this gist https://gist.github.com/agunnerson-ibm/efca449565a3e7356906
  215. fn_human_readable_file_size() {
  216. local abbrevs=(
  217. $((1 << 60)):ZB
  218. $((1 << 50)):EB
  219. $((1 << 40)):TB
  220. $((1 << 30)):GB
  221. $((1 << 20)):MB
  222. $((1 << 10)):KB
  223. $((1)):bytes
  224. )
  225. local bytes="${1}"
  226. local precision="${2}"
  227. if [[ "${bytes}" == "1" ]]; then
  228. echo "1 byte"
  229. else
  230. for item in "${abbrevs[@]}"; do
  231. local factor="${item%:*}"
  232. local abbrev="${item#*:}"
  233. if [[ "${bytes}" -ge "${factor}" ]]; then
  234. local size="$(bc -l <<< "${bytes} / ${factor}")"
  235. printf "%.*f %s\n" "${precision}" "${size}" "${abbrev}"
  236. break
  237. fi
  238. done
  239. fi
  240. }
  241. fn_fastdl_source(){
  242. # Copy all needed files for FastDL
  243. if [ -n "${copyflag}" ]; then
  244. # Removes all existing FastDL files.
  245. if [ -d "${fastdldir}" ]; then
  246. echo -e "removing existing FastDL files"
  247. sleep 0.1
  248. fileswc=1
  249. totalfileswc=$(find "${fastdldir}" | wc -l)
  250. tput sc
  251. while read -r filetoremove; do
  252. tput rc; tput el
  253. printf "removing ${fileswc} / ${totalfileswc} : ${filetoremove}..."
  254. ((fileswc++))
  255. rm -rf "${filetoremove}"
  256. ((exitcode=$?))
  257. if [ ${exitcode} -ne 0 ]; then
  258. fn_script_log_fatal "Removing ${filetoremove}"
  259. break
  260. else
  261. fn_script_log_pass "Removing ${filetoremove}"
  262. fi
  263. sleep 0.01
  264. done < <(find "${fastdldir}")
  265. if [ ${exitcode} -ne 0 ]; then
  266. fn_print_fail_eol_nl
  267. core_exit.sh
  268. else
  269. fn_print_ok_eol_nl
  270. fi
  271. fi
  272. fn_fastdl_dirs
  273. echo -e "copying files to ${fastdldir}"
  274. fn_script_log "copying files to ${fastdldir}"
  275. else
  276. if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then
  277. rm -f "${tmpdir}/fastdl_files_to_compress.txt"
  278. fi
  279. echo -e "analyzing required files"
  280. fn_script_log "analyzing required files"
  281. fi
  282. local directorys_array_=( "maps" "materials" "particles" "sounds" "*.txt" )
  283. for directory in "${directorys_array[@]}"
  284. do
  285. if [ -d "${systemdir}/${directory}" ]; then
  286. if [ "${directory}" == "maps" ]; then
  287. local allowed_extentions_array_=( "*.bsp" "*.ain" "*.nav" "*.jpg" "*.txt" )
  288. elif [ "${directory}" == "materials" ]; then
  289. local allowed_extentions_array=( "*.vtf" "*.vmt" "*.vbf" )
  290. elif [ "${directory}" == "particles" ]; then
  291. local allowed_extentions_array=( "*.pcf" )
  292. elif [ "${directory}" == "sounds" ]; then
  293. local allowed_extentions_array=( "*.vtx" "*.vvd" "*.mdl" "*.mdl" "*.phy" "*.jpg" "*.png" )
  294. fi
  295. for allowed_extention in "${allowed_extentions_array[@]}"
  296. do
  297. fileswc=0
  298. tput sc
  299. if [ -z "${copyflag}" ]; then
  300. tput rc; tput el
  301. printf "gathering ${directory} ${allowed_extention} : ${fileswc}..."
  302. fi
  303. while read -r mapfile; do
  304. ((fileswc++))
  305. if [ -n "${copyflag}" ]; then
  306. tput rc; tput el
  307. printf "copying ${directory} ${allowed_extention} : ${fileswc}..."
  308. if [ ! -d "${fastdldir}/${directory}" ]; then
  309. mkdir "${fastdldir}/${directory}"
  310. fi
  311. cp "${mapfile}" "${fastdldir}/${directory}"
  312. else
  313. tput rc; tput el
  314. printf "gathering ${directory} ${allowed_extention} : ${fileswc}..."
  315. sleep 0.01
  316. echo "${mapfile}" >> "${tmpdir}/fastdl_files_to_compress.txt"
  317. fi
  318. done < <(find "${systemdir}/${directory}" -type f -iname ${allowed_extention})
  319. if [ -z "${copyflag}" ]; then
  320. tput rc; tput el
  321. printf "gathering ${directory} ${allowed_extention} : ${fileswc}..."
  322. fi
  323. if [ ${fileswc} != 0 ]&&[ -n "${copyflag}" ]||[ -z "${copyflag}" ]; then
  324. fn_print_ok_eol_nl
  325. fi
  326. done
  327. fi
  328. done
  329. if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then
  330. totalfiles=$(wc -l < "${tmpdir}/fastdl_files_to_compress.txt")
  331. # Calculates total file size
  332. while read dufile; do
  333. filesize=$(du -b "${dufile}"| awk '{ print $1 }')
  334. filesizetotal=$(( ${filesizetotal} + ${filesize} ))
  335. done <"${tmpdir}/fastdl_files_to_compress.txt"
  336. fi
  337. if [ -z "${copyflag}" ]; then
  338. echo "about to compress ${totalfiles} files, total size $(fn_human_readable_file_size ${filesizetotal} 0) "
  339. if [ -f "${tmpdir}/fastdl_files_to_compress.txt" ]; then
  340. rm "${tmpdir}/fastdl_files_to_compress.txt"
  341. fi
  342. if fn_prompt_yn "Continue?" Y; then
  343. copyflag=1
  344. fn_fastdl_source
  345. else
  346. core_exit.sh
  347. fi
  348. else
  349. fn_fastdl_bzip2
  350. fi
  351. }
  352. # Generate lua file that will force download any file into the FastDL directory
  353. fn_fastdl_gmod_lua_enforcer(){
  354. # Remove lua file if luaressource is turned off and file exists
  355. echo ""
  356. if [ "${luaressource}" == "off" ]; then
  357. if [ -f "${luafastdlfullpath}" ]; then
  358. fn_print_dots "Removing download enforcer"
  359. sleep 1
  360. rm -R "${luafastdlfullpath:?}"
  361. fn_print_ok "Removed download enforcer"
  362. fn_script_log "Removed old download inforcer"
  363. echo -en "\n"
  364. sleep 2
  365. fi
  366. fi
  367. # Remove old lua file and generate a new one if user said yes
  368. if [ "${luaressource}" == "on" ]; then
  369. if [ -f "${luafastdlfullpath}" ]; then
  370. fn_print_dots "Removing old download enforcer"
  371. sleep 1
  372. rm "${luafastdlfullpath}"
  373. fn_print_ok "Removed old download enforcer"
  374. fn_script_log "Removed old download enforcer"
  375. echo -en "\n"
  376. sleep 1
  377. fi
  378. fn_print_dots "Generating new download enforcer"
  379. fn_script_log "Generating new download enforcer"
  380. sleep 1
  381. # Read all filenames and put them into a lua file at the right path
  382. find "${fastdldir:?}" \( -type f ! -name "*.bz2" \) -printf '%P\n' | while read line; do
  383. echo "resource.AddFile( "\""${line}"\"" )" >> "${luafastdlfullpath}"
  384. done
  385. fn_print_ok "Download enforcer generated"
  386. fn_script_log "Download enforcer generated"
  387. echo -en "\n"
  388. echo ""
  389. sleep 2
  390. fi
  391. }
  392. fn_fastdl_bzip2(){
  393. while read -r filetocompress; do
  394. echo -en "compressing ${filetocompress}..."
  395. bzip2 "${filetocompress}"
  396. exitcode=$?
  397. if [ ${exitcode} -ne 0 ]; then
  398. fn_print_fail_eol_nl
  399. fn_script_log_fatal "creating web directory ${webdir}..."
  400. core_exit.sh
  401. else
  402. fn_print_ok_eol_nl
  403. fn_script_log_pass "creating web directory ${webdir}..."
  404. fi
  405. done < <(find "${fastdldir:?}" \( -type f ! -name "*.bz2" \))
  406. }
  407. fn_fastdl_completed(){
  408. # Finished message
  409. echo "FastDL files are located in:"
  410. echo "${webdir}"
  411. echo "FastDL completed"
  412. fn_script_log "FastDL completed"
  413. }
  414. # Run functions
  415. fn_print_header
  416. echo "More info: https://git.io/vyk9a"
  417. echo ""
  418. fn_fastdl_config
  419. if [ "${gamename}" == "Garry's Mod" ]; then
  420. fn_fastdl_gmod
  421. fn_fastdl_gmod_lua_enforcer
  422. else
  423. fn_fastdl_source
  424. fi
  425. fn_fastdl_completed
  426. core_exit.sh