vcmibuilder 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #!/bin/bash
  2. #
  3. # VCMI data builder script
  4. # Extracts game data from various sources and creates a tree with the right files
  5. #
  6. # Authors: listed in file AUTHORS in main folder
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # no console arguments - print help
  14. if [ $# -eq 0 ] ; then
  15. print_help=true
  16. fi
  17. # command line parsing
  18. # can't use system getopt which is not cross-platform (BSD/Mac)
  19. # can't use built-in getopts which can't parse long options (too difficult to avoid - e.g. CD1/CD2)
  20. while [ $# -gt 0 ]
  21. do
  22. case $1 in
  23. --cd1) cd1_dir=$2 ; shift 2 ;;
  24. --cd2) cd2_dir=$2 ; shift 2 ;;
  25. --gog) gog_file=$2 ; shift 2 ;;
  26. --data) data_dir=$2 ; shift 2 ;;
  27. --dest) dest_dir=$2 ; shift 2 ;;
  28. --wog) wog_archive=$2 ; shift 2 ;;
  29. --vcmi) vcmi_archive=$2 ; shift 2 ;;
  30. --convertMP3) useffmpeg=true; shift 1 ;;
  31. --download) download=true ; shift 1 ;;
  32. --validate) validate=true ; shift 1 ;;
  33. *) print_help=true ; shift 1 ;;
  34. esac
  35. done
  36. if [[ -n "$print_help" ]]
  37. then
  38. echo "VCMI data builder utility"
  39. echo "Usage: vcmibuilder <options>"
  40. echo "Options:"
  41. echo " --cd1 DIRECTORY " "Path to mounted first CD with Heroes 3 install files"
  42. echo " " "Requires unshield"
  43. echo
  44. echo " --cd2 DIRECTORY " "Path to second CD with Heroes 3 data files."
  45. echo
  46. echo " --gog EXECUTABLE " "Path to gog.com executable"
  47. echo " " "Requires innoextract ( http://constexpr.org/innoextract/ )"
  48. echo
  49. echo " --data DIRECTORY " "Path to installed Heroes 3 data"
  50. echo
  51. echo " --wog ARCHIVE " "Path to manually downloaded WoG archive"
  52. echo " " "Requires unzip"
  53. echo
  54. echo " --vcmi ARCHIVE " "Path to manually downloaded VCMI data package"
  55. echo " " "Requires unzip"
  56. echo
  57. echo " --convertMP3 " "Convert all mp3 files into ogg/vorbis"
  58. echo " " "Requires ffmpeg"
  59. echo
  60. echo " --download " "Automatically download requied packages using wget"
  61. echo " " "Requires wget and Internet connection"
  62. echo
  63. echo " --dest DIRECTORY " "Path where resulting data will be placed. Default is ~/.vcmi"
  64. echo
  65. echo " --validate " "Run basic validness checks"
  66. exit 0
  67. fi
  68. # test presence of program $1, $2 will be passed as parameters to test presence
  69. test_utility ()
  70. {
  71. $1 $2 > /dev/null 2>&1 || { echo "$1 was not found. Please install it" 1>&2 ; exit 1; }
  72. }
  73. #print error message and exit
  74. fail ()
  75. {
  76. $2
  77. echo "$1" 1>&2
  78. rm -rf "$temp_dir"
  79. exit 1
  80. }
  81. # print warning to stderr.
  82. warning ()
  83. {
  84. echo "$1" 1>&2
  85. warn_user=true
  86. }
  87. # check if selected options are correct.
  88. if [[ -n "$data_dir" ]]
  89. then
  90. if [[ -n "$gog_file" ]] || [[ -n "$cd1_dir" ]] || [[ -n "$cd2_dir" ]]
  91. then
  92. warning "Warning: Installed data dir was specified. Both gog and cd options will be ignored"
  93. unset gog_file cd1_dir cd2_dir
  94. fi
  95. fi
  96. if [[ -n "$gog_file" ]]
  97. then
  98. test_utility "innoextract"
  99. if [[ -n "$cd1_dir" ]] || [[ -n "$cd2_dir" ]]
  100. then
  101. warning "Warning: Both gog and cd options were specified. cd options will be ignored"
  102. unset cd1_dir cd2_dir
  103. fi
  104. fi
  105. if [[ -n "$useffmpeg" ]]
  106. then
  107. test_utility "ffmpeg" "-version"
  108. fi
  109. if [[ -n "$cd1_dir" ]]
  110. then
  111. test_utility "unshield" "-V"
  112. fi
  113. if [[ -n "$download" ]]
  114. then
  115. if [[ -n "$wog_archive" ]] && [[ -n "$vcmi_archive" ]]
  116. then
  117. warning "Warning: Both wog and vcmi archives were specified. Download option will not be used"
  118. unset download
  119. else
  120. test_utility "wget" "-V"
  121. fi
  122. fi
  123. if [[ -n "$download" ]] || [[ -n "$wog_archive" ]] || [[ -n "$vcmi_archive" ]]
  124. then
  125. test_utility "unzip"
  126. fi
  127. if [[ -z "$gog_file" ]] && [[ -z "$data_dir" ]] && ( [[ -z "$cd1_dir" ]] || [[ -z "$cd2_dir" ]] )
  128. then
  129. warning "Warning: Selected options will not create complete Heroes 3 data!"
  130. fi
  131. if [[ -z "$download" ]] && ( [[ -z "$wog_archive" ]] || [[ -z "$vcmi_archive" ]])
  132. then
  133. warning "Warning: Selected options will not create complete VCMI data!"
  134. fi
  135. # if at least one warning has been printed - ask for confirmation
  136. if [[ -n "$warn_user" ]]
  137. then
  138. read -p "Do you wish to continue? (y/n) " -n 1
  139. echo #print eol
  140. if [[ ! $REPLY =~ ^[Yy]$ ]]
  141. then
  142. exit 1
  143. fi
  144. fi
  145. if [[ -z "$dest_dir" ]]
  146. then
  147. dest_dir="$HOME/.vcmi"
  148. fi
  149. temp_dir="$dest_dir"/buildertmp
  150. # start installation
  151. mkdir -p "$dest_dir"
  152. mkdir -p "$temp_dir"
  153. if [[ -n "$gog_file" ]]
  154. then
  155. # innoextract always reports error (iconv 84 error). Just test file for presence
  156. test -f "$gog_file" || fail "Error: gog.com executable was not found!"
  157. (gog_file=`readlink -f "$gog_file"` && cd "$temp_dir" && innoextract -s -p 1 "$gog_file")
  158. data_dir="$temp_dir"/app
  159. fi
  160. if [[ -n "$cd1_dir" ]]
  161. then
  162. data_dir="$temp_dir"/cddir
  163. mkdir -p "$data_dir"
  164. unshield -d "$data_dir" x "$cd1_dir"/_setup/data1.cab || fail "Error: failed to extract from Install Shield installer!" "rm -rf $data_dir"
  165. # a bit tricky - different releases have different root directory. Move extracted files to data_dir
  166. if [ -d "$data_dir"/Heroes3 ]
  167. then
  168. mv "$data_dir"/Heroes3/* "$data_dir"
  169. elif [ -d "$data_dir""/Program_Files" ]
  170. then
  171. mv "$data_dir"/Program_Files/* "$data_dir"
  172. else
  173. echo "Error: failed to find extracted game files!"
  174. echo "Extracted directories are: "
  175. ls -la "$data_dir"
  176. echo "Please report this on vcmi.eu"
  177. exit 1;
  178. fi
  179. fi
  180. if [[ -n "$cd2_dir" ]]
  181. then
  182. mkdir -p "$dest_dir"/Data
  183. if [ -d "$cd2_dir"/heroes3 ]
  184. then
  185. cp "$cd2_dir"/heroes3/Data/Heroes3.vid "$dest_dir"/Data/Heroes3.vid
  186. cp "$cd2_dir"/heroes3/Data/Heroes3.snd "$dest_dir"/Data/Heroes3-cd2.snd
  187. else
  188. cp "$cd2_dir"/Heroes3/Data/Heroes3.vid "$dest_dir"/Data/Heroes3.vid
  189. cp "$cd2_dir"/Heroes3/Data/Heroes3.snd "$dest_dir"/Data/Heroes3-cd2.snd
  190. fi
  191. fi
  192. if [[ -n "$data_dir" ]]
  193. then
  194. cp -r "$data_dir"/Data "$dest_dir"
  195. cp -r "$data_dir"/Maps "$dest_dir"
  196. # this folder is named differently from time to time
  197. # vcmi can handle any case but script can't
  198. if [ -d "$data_dir"/MP3 ]
  199. then
  200. cp -r "$data_dir"/MP3 "$dest_dir"
  201. else
  202. cp -r "$data_dir"/Mp3 "$dest_dir"
  203. fi
  204. fi
  205. if [[ -n "$download" ]]
  206. then
  207. if [[ -z "$wog_archive" ]]
  208. then
  209. wget "http://download.vcmi.eu/WoG/wog.zip" -O "$temp_dir"/wog.zip || fail "Error: failed to download WoG archive!" "rm -f wog.zip"
  210. wog_archive="$temp_dir"/wog.zip
  211. fi
  212. if [[ -z "$vcmi_archive" ]]
  213. then
  214. wget "http://download.vcmi.eu/core.zip" -O "$temp_dir"/core.zip || fail "Error: failed to download VCMI archive!" "rm -f core.zip"
  215. vcmi_archive="$temp_dir"/core.zip
  216. fi
  217. fi
  218. if [[ -n "$wog_archive" ]]
  219. then
  220. echo "decompressing $wog_archive"
  221. unzip -qo "$wog_archive" -d "$dest_dir" || fail "Error: failed to extract WoG archive!"
  222. fi
  223. if [[ -n "$vcmi_archive" ]]
  224. then
  225. echo "decompressing $vcmi_archive"
  226. unzip -qo "$vcmi_archive" -d "$dest_dir" || fail "Error: failed to extract VCMI archive!"
  227. fi
  228. if [[ -n "$useffmpeg" ]]
  229. then
  230. # now when all music files (including WoG theme) were installed convert them to ogg
  231. echo "Converting mp3 files..."
  232. OIFS="$IFS"
  233. IFS=$'\n'
  234. for file in `find "$dest_dir" -type f -name "*.mp3"`
  235. do
  236. echo "Converting $file"
  237. ogg=${file%.*}
  238. ffmpeg -y -i "$file" -acodec libvorbis "$ogg".ogg 2>/dev/null || fail "Error: failed to convert $file to ogg/vorbis using ffmpeg" "rm -f "$ogg".ogg"
  239. rm -f $file
  240. done
  241. IFS="$OIFS"
  242. fi
  243. if [[ -n "$validate" ]]
  244. then
  245. test -f "$dest_dir"/Data/H3bitmap.lod || fail "Error: Heroes 3 data files are missing!"
  246. test -f "$dest_dir"/Data/H3sprite.lod || fail "Error: Heroes 3 data files are missing!"
  247. test -f "$dest_dir"/Data/VIDEO.VID || fail "Error: Heroes 3 data files (CD2) are missing!"
  248. test -d "$dest_dir"/Mods/WoG/Data || fail "Error: WoG data files are missing!"
  249. test -d "$dest_dir"/Mods/vcmi/Data || fail "Error: VCMI data files are missing!"
  250. fi
  251. rm -rf "$temp_dir"