install.sh 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #!/usr/bin/env bash
  2. # Grasscutter install script for GNU/Linux
  3. # Made by TurtleIdiot
  4. # Stops the installer if any command has a non-zero exit status
  5. set -e
  6. # Checks for root
  7. if [ $EUID != 0 ]; then
  8. echo "Please run the installer as root!"
  9. exit
  10. fi
  11. is_command() {
  12. # Checks if a given command is available
  13. local check_command="$1"
  14. command -v "${check_command}" > /dev/null 2>&1
  15. }
  16. # IP validation
  17. valid_ip() {
  18. local ip=$1
  19. local stat=1
  20. if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
  21. OIFS=$IFS
  22. IFS="."
  23. ip=($ip)
  24. IFS=$OIFS
  25. [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
  26. && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
  27. stat=$?
  28. fi
  29. return $stat
  30. }
  31. # Checks for supported installer(s) (only apt-get and pacman right now, might add more in the future)
  32. if is_command apt-get ; then
  33. echo -e "Supported package manager found (apt-get)\n"
  34. GC_DEPS="mongodb openjdk-17-jre"
  35. INSTALLER_DEPS="wget openssl unzip git"
  36. SYSTEM="deb" # Debian-based (debian, ubuntu)
  37. elif is_command pacman ; then
  38. echo -e "supported package manager found (pacman)\n"
  39. GC_DEPS="jre17-openjdk"
  40. INSTALLER_DEPS="curl wget openssl unzip git base-devel" # curl is still a dependency here in order to successfully build mongodb
  41. SYSTEM="arch" # Arch for the elitists :P
  42. else
  43. echo "No supported package manager found"
  44. exit
  45. fi
  46. BRANCH="stable" # Stable by default
  47. # Allows choice between stable and dev branch
  48. echo "Please select the branch you wish to install"
  49. echo -e "!!NOTE!!: stable is the recommended branch.\nDo *NOT* use development unless you have a reason to and know what you're doing"
  50. select branch in "stable" "development" ; do
  51. case $branch in
  52. stable )
  53. BRANCH="stable"
  54. break;;
  55. development )
  56. BRANCH="development"
  57. break;;
  58. esac
  59. done
  60. echo "The following packages will have to be installed in order to INSTALL grasscutter:"
  61. echo -e "$INSTALLER_DEPS \n"
  62. echo "The following packages will have to be installed to RUN grasscutter:"
  63. echo -e "$GC_DEPS \n"
  64. echo "Do you wish to proceed and install grasscutter?"
  65. select yn in "Yes" "No" ; do
  66. case $yn in
  67. Yes ) break;;
  68. No ) exit;;
  69. esac
  70. done
  71. echo "Updating package cache..."
  72. case $SYSTEM in # More concise than if
  73. deb ) apt-get update -qq;;
  74. arch ) pacman -Syy;;
  75. esac
  76. # Starts installing dependencies
  77. echo "Installing setup dependencies..."
  78. case $SYSTEM in # These are one-liners anyways
  79. deb ) apt-get -qq install $INSTALLER_DEPS -y;;
  80. arch ) pacman -Sq --noconfirm --needed $INSTALLER_DEPS > /dev/null;;
  81. esac
  82. echo "Done"
  83. echo "Installing grasscutter dependencies..."
  84. case $SYSTEM in
  85. deb) apt-get -qq install $GC_DEPS -y > /dev/null;;
  86. arch ) pacman -Sq --noconfirm --needed $GC_DEPS > /dev/null;;
  87. esac
  88. # *sighs* here we go...
  89. INST_ARCH_MONGO="no"
  90. if [ $SYSTEM = "arch" ]; then
  91. echo -e "-=-=-=-=-=--- !! IMPORTANT !! ---=-=-=-=-=-\n"
  92. echo -e " Due to licensing issues with mongodb,\n it is no longer available on the official arch repositiries."
  93. echo -e " In order to install mongodb,\n it needs to be fetched from the Arch User Repository.\n"
  94. echo -e " As this script is running as root,\n a temporary user will need to be created to run makepkg."
  95. echo -e " The temporary user will be deleted once\n makepkg has finished.\n"
  96. echo -e " This will be handled automatically.\n"
  97. echo -e "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
  98. echo -e "!!NOTE!!: Only select \"Skip\" if mongodb is already installed on this system"
  99. echo "Do you want to continue?"
  100. select yn in "Yes" "Skip" "No" ; do
  101. case $yn in
  102. Yes )
  103. INST_ARCH_MONGO="yes"
  104. break;;
  105. No ) exit;;
  106. Skip )
  107. INST_ARCH_MONGO="no"
  108. break;;
  109. esac
  110. done
  111. fi
  112. if [ $INST_ARCH_MONGO = "yes" ]; then
  113. DIR=$(pwd)
  114. # Make temp user
  115. echo "Creating temporary user..."
  116. TEMPUSER="gctempuser"
  117. TEMPHOME="/home/$TEMPUSER"
  118. useradd -m $TEMPUSER
  119. cd $TEMPHOME
  120. # Do the actual makepkg shenanigans
  121. echo "Building mongodb... (this will take a moment)"
  122. su $TEMPUSER<<EOF
  123. mkdir temp
  124. cd temp
  125. git clone https://aur.archlinux.org/mongodb-bin.git -q
  126. cd mongodb-bin
  127. makepkg -s > /dev/null
  128. exit
  129. EOF
  130. mv "$(find -name "mongodb-bin*.pkg.tar.zst" -type f)" ./mongodb-bin.pkg.tar.zst
  131. cd $DIR
  132. # Snatch the file to current working directory
  133. mv "$TEMPHOME/mongodb-bin.pkg.tar.zst" ./mongodb-bin.pkg.tar.zst
  134. chown root ./mongodb-bin.pkg.tar.zst
  135. chgrp root ./mongodb-bin.pkg.tar.zst
  136. chmod 775 ./mongodb-bin.pkg.tar.zst
  137. echo "Installing mongodb..."
  138. pacman -U mongodb-bin.pkg.tar.zst --noconfirm > /dev/null
  139. rm mongodb-bin.pkg.tar.zst
  140. echo "Starting mongodb..."
  141. systemctl enable mongodb
  142. systemctl start mongodb
  143. echo "Removing temporary account..."
  144. userdel -r $TEMPUSER
  145. fi
  146. echo "Done"
  147. echo "Getting grasscutter..."
  148. # Download and rename jar
  149. wget -q --show-progress "https://nightly.link/Grasscutters/Grasscutter/workflows/build/$BRANCH/Grasscutter.zip"
  150. echo "unzipping"
  151. unzip -qq Grasscutter.zip
  152. mv $(find -name "grasscutter*.jar" -type f) grasscutter.jar
  153. # Download resources
  154. echo "Downloading resources... (this will take a moment)"
  155. wget -q --show-progress https://github.com/Koko-boya/Grasscutter_Resources/archive/refs/heads/main.zip -O resources.zip
  156. echo "Extracting..."
  157. unzip -qq resources.zip
  158. mv ./Grasscutter_Resources-main/Resources ./resources
  159. # Here we do a sparse checkout to only pull /data and /keys
  160. echo "Downloading keys and data..."
  161. mkdir repo
  162. cd repo
  163. git init -q
  164. git remote add origin https://github.com/Grasscutters/Grasscutter.git
  165. git fetch -q
  166. git config core.sparseCheckout true
  167. echo "data/" >> .git/info/sparse-checkout
  168. echo "keys/" >> .git/info/sparse-checkout
  169. git pull origin stable -q
  170. cd ../
  171. mv ./repo/data ./data
  172. mv ./repo/keys ./keys
  173. # Generate handbook/config
  174. echo "Please enter language when *NEXT* prompted (press enter/return to continue to language select)"
  175. read
  176. java -jar grasscutter.jar -handbook
  177. # Prompt IP address for config.json and for generating new keystore.p12 file
  178. echo "Please enter the IP address that will be used to connect to the server"
  179. echo "This can be a local or a public IP address"
  180. echo "This IP address will be used to generate SSL certificates so it is important it is correct"
  181. while : ; do
  182. read -p "Enter IP: " SERVER_IP
  183. if valid_ip $SERVER_IP; then
  184. break;
  185. else
  186. echo "Invalid IP address. Try again."
  187. fi
  188. done
  189. # Replaces "127.0.0.1" with given IP
  190. sed -i "s/127.0.0.1/$SERVER_IP/g" config.json
  191. # Generates new keystore.p12 with the server's IP address
  192. # This is done to prevent a "Connection Timed Out" error from appearing
  193. # after clicking to enter the door in the main menu/title screen
  194. # This issue only exists when connecting to a server *other* than localhost
  195. # since the default keystore.p12 has only been made for localhost
  196. mkdir certs
  197. cd certs
  198. echo "Generating CA key and certificate pair..."
  199. openssl req -x509 -nodes -days 25202 -newkey rsa:2048 -subj "/C=GB/ST=Essex/L=London/O=Grasscutters/OU=Grasscutters/CN=$SERVER_IP" -keyout CAkey.key -out CAcert.crt
  200. echo "Generating SSL key and certificate pair..."
  201. openssl genpkey -out ssl.key -algorithm rsa
  202. # Creates a conf file in order to generate a csr
  203. cat > csr.conf <<EOF
  204. [ req ]
  205. default_bits = 2048
  206. prompt = no
  207. default_md = sha256
  208. req_extensions = req_ext
  209. distinguished_name = dn
  210. [ dn ]
  211. C = GB
  212. ST = Essex
  213. L = London
  214. O = Grasscutters
  215. OU = Grasscutters
  216. CN = $SERVER_IP
  217. [ req_ext ]
  218. subjectAltName = @alt_names
  219. [ alt_names ]
  220. IP.1 = $SERVER_IP
  221. EOF
  222. # Creates csr using key and conf
  223. openssl req -new -key ssl.key -out ssl.csr -config csr.conf
  224. # Creates conf to finalise creation of certificate
  225. cat > cert.conf <<EOF
  226. authorityKeyIdentifier=keyid,issuer
  227. basicConstraints=CA:FALSE
  228. keyUsage = digitalSignature, nonRepudiation, keyEncipherment, keyAgreement, dataEncipherment
  229. subjectAltName = @alt_names
  230. [alt_names]
  231. IP.1 = $SERVER_IP
  232. EOF
  233. # Creates ssl cert
  234. openssl x509 -req -in ssl.csr -CA CAcert.crt -CAkey CAkey.key -CAcreateserial -out ssl.crt -days 25202 -sha256 -extfile cert.conf
  235. echo "Generating keystore.p12 from key and certificate..."
  236. openssl pkcs12 -export -out keystore.p12 -inkey ssl.key -in ssl.crt -certfile CAcert.crt -passout pass:123456
  237. cd ../
  238. mv ./certs/keystore.p12 ./keystore.p12
  239. echo "Done"
  240. echo -e "Asking Noelle to clean up...\n"
  241. rm -rf Grasscutter.zip resources.zip ./certs ./Grasscutter_Resources-main ./repo
  242. echo -e "All done!\n"
  243. echo -e "You can now uninstall the following packages if you wish:\n$INSTALLER_DEPS"
  244. echo -e "-=-=-=-=-=--- !! IMPORTANT !! ---=-=-=-=-=-\n"
  245. echo "Please make sure that ports 443 and 22102 are OPEN (both tcp and udp)"
  246. echo -e "In order to run the server, run the following command:\nsudo java -jar grasscutter.jar"
  247. echo "You must run it using sudo as port 443 is a privileged port"
  248. echo "To play, use the IP you provided earlier ($SERVER_IP) via GrassClipper or Fiddler"
  249. exit