install.sh 9.58 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env bash

# Grasscutter install script for linux
# Made by TurtleIdiot

# Stops the installer if any command has a non-zero exit status
set -e

# Checks for root
if [ $EUID != 0 ]; then
        echo "Please run the installer as root!"
        exit
fi

is_command() {
        # Checks if a given command is available
        local check_command="$1"
        command -v "${check_command}" > /dev/null 2>&1
}

# IP validation
valid_ip() {
        local ip=$1
        local stat=1

        if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
                OIFS=$IFS
                IFS="."
                ip=($ip)
                IFS=$OIFS
                [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
                        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
                stat=$?
        fi
        return $stat
}

TurtleIdiot's avatar
TurtleIdiot committed
38
# Checks for supported installer(s) (only apt-get and pacman right now, might add more in the future)
39
if is_command apt-get ; then
TurtleIdiot's avatar
TurtleIdiot committed
40
41
42
43
44
45
46
47
48
49
50
        echo -e "Supported package manager found (apt-get)\n"

        GC_DEPS="mongodb openjdk-17-jre"
        INSTALLER_DEPS="wget openssl unzip git"
        SYSTEM="deb" # Debian-based (debian, ubuntu)
elif is_command pacman ; then
        echo -e "supported package manager found (pacman)\n"

        GC_DEPS="jre17-openjdk"
        INSTALLER_DEPS="curl wget openssl unzip git base-devel" # curl is still a dependency here in order to successfully build mongodb
        SYSTEM="arch" # Arch for the elitists :P
51
52
53
54
55
else
        echo "No supported package manager found"
        exit
fi

56
57
58
BRANCH="stable" # Stable by default
# Allows choice between stable and dev branch
echo "Please select the branch you wish to install"
TurtleIdiot's avatar
TurtleIdiot committed
59
echo -e "!!NOTE!!: stable is the recommended branch.\nDo *NOT* use development unless you have a reason to and know what you're doing"
60
select branch in "stable" "development" ; do
TurtleIdiot's avatar
TurtleIdiot committed
61
62
63
64
65
66
67
68
        case $branch in
                stable )
                        BRANCH="stable"
                        break;;
                development )
                        BRANCH="development"
                        break;;
        esac
69
70
done

71
72
73
74
75
76
77
78
79
80
81
82
83
84
echo "The following packages will have to be installed in order to INSTALL grasscutter:"
echo -e "$INSTALLER_DEPS \n"
echo "The following packages will have to be installed to RUN grasscutter:"
echo -e "$GC_DEPS \n"

echo "Do you wish to proceed and install grasscutter?"
select yn in "Yes" "No" ; do
        case $yn in
                Yes ) break;;
                No ) exit;;
        esac
done

echo "Updating package cache..."
TurtleIdiot's avatar
TurtleIdiot committed
85
86
87
88
case $SYSTEM in # More concise than if
        deb ) apt-get update -qq;;
        arch ) pacman -Syy;;
esac
89
90
91

# Starts installing dependencies
echo "Installing setup dependencies..."
TurtleIdiot's avatar
TurtleIdiot committed
92
93
94
95
case $SYSTEM in # These are one-liners anyways
        deb ) apt-get -qq install $INSTALLER_DEPS -y;;
        arch ) pacman -Sq --noconfirm --needed $INSTALLER_DEPS > /dev/null;;
esac
96
97
98
echo "Done"

echo "Installing grasscutter dependencies..."
TurtleIdiot's avatar
TurtleIdiot committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
case $SYSTEM in
        deb) apt-get -qq install $GC_DEPS -y > /dev/null;;
        arch ) pacman -Sq --noconfirm --needed $GC_DEPS > /dev/null;;
esac
# *sighs* here we go...
INST_ARCH_MONGO="no"
if [ $SYSTEM = "arch" ]; then
        echo -e "-=-=-=-=-=--- !! IMPORTANT !! ---=-=-=-=-=-\n"
        echo -e "    Due to licensing issues with mongodb,\n    it is no longer available on the official arch repositiries."
        echo -e "    In order to install mongodb,\n    it needs to be fetched from the Arch User Repository.\n"
        echo -e "    As this script is running as root,\n    a temporary user will need to be created to run makepkg."
        echo -e "    The temporary user will be deleted once\n    makepkg has finished.\n"
        echo -e "    This will be handled automatically.\n"
        echo -e "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
        echo -e "!!NOTE!!: Only select \"Skip\" if mongodb is already installed on this system"
        echo "Do you want to continue?"
        select yn in "Yes" "Skip" "No" ; do
                case $yn in
                        Yes )
                                INST_ARCH_MONGO="yes"
                                break;;
                        No ) exit;;
                        Skip )
                                INST_ARCH_MONGO="no"
                                break;;
                esac
        done
fi

if [ $INST_ARCH_MONGO = "yes" ]; then
        DIR=$(pwd)
        # Make temp user
        echo "Creating temporary user..."
        TEMPUSER="gctempuser"
        TEMPHOME="/home/$TEMPUSER"
        useradd -m $TEMPUSER
        cd $TEMPHOME

        # Do the actual makepkg shenanigans
        echo "Building mongodb... (this will take a moment)"
        su $TEMPUSER<<EOF
                mkdir temp
                cd temp
                git clone https://aur.archlinux.org/mongodb-bin.git -q
                cd mongodb-bin
                makepkg -s > /dev/null
                exit
EOF
        mv "$(find -name "mongodb-bin*.pkg.tar.zst" -type f)" ./mongodb-bin.pkg.tar.zst
        cd $DIR

        # Snatch the file to current working directory
        mv "$TEMPHOME/mongodb-bin.pkg.tar.zst" ./mongodb-bin.pkg.tar.zst
        chown root ./mongodb-bin.pkg.tar.zst
        chgrp root ./mongodb-bin.pkg.tar.zst
        chmod 775 ./mongodb-bin.pkg.tar.zst

        echo "Installing mongodb..."
        pacman -U mongodb-bin.pkg.tar.zst --noconfirm > /dev/null
        rm mongodb-bin.pkg.tar.zst

        echo "Starting mongodb..."
        systemctl enable mongodb
        systemctl start mongodb

        echo "Removing temporary account..."
        userdel -r $TEMPUSER
fi
167
168
169
170
171
echo "Done"

echo "Getting grasscutter..."

# Download and rename jar
172
wget -q --show-progress "https://nightly.link/Grasscutters/Grasscutter/workflows/build/$BRANCH/Grasscutter.zip"
TurtleIdiot's avatar
TurtleIdiot committed
173
echo "unzipping"
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
unzip -qq Grasscutter.zip
mv $(find -name "grasscutter*.jar" -type f) grasscutter.jar

# Download resources
echo "Downloading resources... (this will take a moment)"
wget -q --show-progress https://github.com/Koko-boya/Grasscutter_Resources/archive/refs/heads/main.zip -O resources.zip
echo "Extracting..."
unzip -qq resources.zip
mv ./Grasscutter_Resources-main/Resources ./resources

# Here we do a sparse checkout to only pull /data and /keys
echo "Downloading keys and data..."
mkdir repo
cd repo
git init -q
git remote add origin https://github.com/Grasscutters/Grasscutter.git
git fetch -q
git config core.sparseCheckout true
echo "data/" >> .git/info/sparse-checkout
echo "keys/" >> .git/info/sparse-checkout
git pull origin stable -q
cd ../
mv ./repo/data ./data
mv ./repo/keys ./keys

# Generate handbook/config
TurtleIdiot's avatar
TurtleIdiot committed
200
echo "Please enter language when *NEXT* prompted (press enter/return to continue to language select)"
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
read
java -jar grasscutter.jar -handbook

# Prompt IP address for config.json and for generating new keystore.p12 file
echo "Please enter the IP address that will be used to connect to the server"
echo "This can be a local or a public IP address"
echo "This IP address will be used to generate SSL certificates so it is important it is correct"

while : ; do
        read -p "Enter IP: " SERVER_IP
        if valid_ip $SERVER_IP; then
                break;
        else
                echo "Invalid IP address. Try again."
        fi
done

# Replaces "127.0.0.1" with given IP
sed -i "s/127.0.0.1/$SERVER_IP/g" config.json

# Generates new keystore.p12 with the server's IP address
# This is done to prevent a "Connection Timed Out" error from appearing
#       after clicking to enter the door in the main menu/title screen
# This issue only exists when connecting to a server *other* than localhost
#       since the default keystore.p12 has only been made for localhost

mkdir certs
cd certs
echo "Generating CA key and certificate pair..."
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
echo "Generating SSL key and certificate pair..."

openssl genpkey -out ssl.key -algorithm rsa

# Creates a conf file in order to generate a csr
cat > csr.conf <<EOF
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = GB
ST = Essex
L = London
O = Grasscutters
OU = Grasscutters
CN = $SERVER_IP

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
IP.1 = $SERVER_IP
EOF

# Creates csr using key and conf
openssl req -new -key ssl.key -out ssl.csr -config csr.conf

# Creates conf to finalise creation of certificate
cat > cert.conf <<EOF

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, keyAgreement, dataEncipherment
subjectAltName = @alt_names

[alt_names]
IP.1 = $SERVER_IP

EOF

# Creates ssl cert
openssl x509 -req -in ssl.csr -CA CAcert.crt -CAkey CAkey.key -CAcreateserial -out ssl.crt -days 25202 -sha256 -extfile cert.conf

echo "Generating keystore.p12 from key and certificate..."
openssl pkcs12 -export -out keystore.p12 -inkey ssl.key -in ssl.crt -certfile CAcert.crt -passout pass:123456

cd ../
mv ./certs/keystore.p12 ./keystore.p12
echo "Done"

TurtleIdiot's avatar
TurtleIdiot committed
285
echo -e "Asking Noelle to clean up...\n"
286
rm -rf Grasscutter.zip resources.zip ./certs ./Grasscutter_Resources-main ./repo
TurtleIdiot's avatar
TurtleIdiot committed
287
echo -e "All done!\n"
288
echo -e "You can now uninstall the following packages if you wish:\n$INSTALLER_DEPS"
TurtleIdiot's avatar
TurtleIdiot committed
289
290
echo -e "-=-=-=-=-=--- !! IMPORTANT !! ---=-=-=-=-=-\n"
echo "Please make sure that ports 443 and 22102 are OPEN (both tcp and udp)"
291
292
293
294
295
echo -e "In order to run the server, run the following command:\nsudo java -jar grasscutter.jar"
echo "You must run it using sudo as port 443 is a privileged port"
echo "To play, use the IP you provided earlier ($SERVER_IP) via GrassClipper or Fiddler"

exit