diff --git a/assets/images/2.0-launcher-adding-simple-server.png b/assets/images/2.0-launcher-adding-simple-server.png new file mode 100644 index 0000000..2bcd55e Binary files /dev/null and b/assets/images/2.0-launcher-adding-simple-server.png differ diff --git a/assets/images/2.0-launcher-fresh-start.png b/assets/images/2.0-launcher-fresh-start.png new file mode 100644 index 0000000..8c0698b Binary files /dev/null and b/assets/images/2.0-launcher-fresh-start.png differ diff --git a/content/docs/guides/hosting-a-server.md b/content/docs/guides/hosting-a-server.md index 97af56e..d7818ee 100644 --- a/content/docs/guides/hosting-a-server.md +++ b/content/docs/guides/hosting-a-server.md @@ -23,3 +23,5 @@ seo: 4. Once you've added the server to the list, connect to it and log in. If the account does not exist yet, it will be created automatically. If you run into any issues, try checking [the FAQ](/docs/reference/frequently-asked-questions) or ask for assistance in our Discord server. + +For a more detailed guide see [Setting Up Your Own Server](/docs/guides/setting-up-your-own-server). diff --git a/content/docs/guides/setting-up-your-own-server.md b/content/docs/guides/setting-up-your-own-server.md new file mode 100644 index 0000000..52d49e6 --- /dev/null +++ b/content/docs/guides/setting-up-your-own-server.md @@ -0,0 +1,505 @@ +--- +title: "Hosting a Server" +description: "" +summary: "" +date: 2024-07-14T17:57:37-05:00 +lastmod: 2024-10-10T17:19:07+02:00 +draft: false +weight: 720 +toc: true +seo: + title: "How to host an OpenFusion server" + description: "This guide describes in depth how to setup your own OpenFusion server" + canonical: "" + noindex: false +--- + +There are essentially 2 ways you can host your own OpenFusion server, the first is if you just want to play by yourself on your computer, +in which case you'll run both the server and the launcher in the same machine. The other is to host the server in a separate machine, available +via the network, in which you'll just run the launcher on your computer and connect to the server running on another machine. This second option +allows for other users to connect to your server and play with you. In this guide we'll cover both scenarios in depth. + +# Getting started + +Start by downloading the latest version of the Server [here](https://github.com/OpenFusionProject/OpenFusion/releases). There are versions for both Windows and Linux, make sure to download the correct one for the platform you'll be hosting the server on. + +Extract all the `.zip` files and you're good to go! + +One thing to notice here is that the files you downloaded are only the code of the server, the game assets are not included here, so you'll still need an internet connection to play the game, as the launcher will download the assets from an OpenFusion server on startup. + +# Understanding Server Versions + +OpenFusion supports two main versions of the game: + +* **Original:** The original version of the game, with the Future. +* **Academy:** Relaunch of the game where Cartoon Network removed the Future and added more content. + +When you download the server files, you'll choose which version you want to host. It's also possible to run both versions on the same machine, but they will require separate configurations, which we'll cover in this guide. + +Through out this guide versions are mentioned a lot, so use this section as reference for all the version information. + +## Launcher Configuration + +When adding a server to the OpenFusion Launcher, you must select the correct version for the server you are connecting to. These are the main versions to play: + +* **Original:** `beta-20100104` +* **Academy:** `beta-20111013` + +## API (Endpoint Server) Configuration + +If you decide to set up an endpoint server with OpenFusion API, you will need to use an UUID for each version instead of their names, more on that in the [Making an endpoint server](#making-an-endpoint-server) section. + +* **Original:** `ec8063b2-54d4-4ee1-8d9e-381f5babd420` +* **Academy:** `6543a2bb-d154-4087-b9ee-3c8aa778580a` + +# Part 1: Hosting a Server for Solo Play + +If all you want is to play the game by yourself on your own computer, the setup is very straight forward. All you have to do is start the server by running its executable file, `winfusion.exe` if you're on Windows or `fusion` if you're on Linux. + +Once the server is running, open the Launcher. Note it comes with the `OpenFusion Original` and `OpenFusion Academy` servers pre-configured for you. + +{{< figure + src="images/2.0-launcher-fresh-start.png" + alt="Launcher on a fresh installation" +>}} + +To add your local server to the list, click on the `+` icon on the bottom left corner of the server list. This will open a pop-up for you to enter your server's information. Since you are playing locally, you can leave the default settings as they are. + +The most important thing on this screen is the version selector. Make sure it matches the server version you are running. + +{{< figure + src="images/2.0-launcher-adding-simple-server.png" + alt="Adding a simple server" +>}} + +# Part 2: Hosting a Server for Multiplayer + +The setup for a multiplayer server is not so different from a solo server, but it requires more configuration to make it available to other players, either on your local network or over the internet. + +## Important notes + ++ The OpenFusion server *does not* run on the HTTP protocol. That means that you can not put it behind a HTTP proxy, like Nginx. ++ From this point on this guide will get more technical, however, it won't go in depth on the technicalities. There will be references and suggestions on tools to use and where to find tutorials for those tools. Nothing here is too complicated and there are many good tutorials today on these topics. ++ The exact steps that you need to take for each part of the setup will vary depending on the architecture you're using here. For example, a homelab is different than using a VPS. This guide will describe what needs to be setup and how, but you will have to look into how exactly to set it up for your case. + +## Automated Server Setup (Linux Only) + +If you're running the server on linux there's an automated bootstrapping script that will set up a basic OpenFusion Server for you. + +Run the commands bellow directly in a terminal to download and run the bootstrapping script. + +```bash +# Download the script +wget https://openfusionproject.github.io/openfusion-server-bootstrapper.sh + +# Make it executable +chmod +x openfusion-server-bootstrapper.sh + +# Run the script as root +sudo ./openfusion-server-bootstrapper.sh +``` + +The script will guide you through the setup process with interactive prompts. For help and additional options, run: + +```bash +./openfusion-server-bootstrapper.sh --help +``` + +**Note:** The bootstrapper automates most of the steps described in the manual sections below. If you prefer to understand each step or need to customize your setup beyond what the script offers, continue with the manual configuration sections. + +## Manual Configuration + +If you're not using the automated bootstrapper, or if you're on Windows, follow the manual setup instructions below. + +### Configuring the server + +The first thing you want to do is download the Server files as described in the beginning of this guide. Once you have the server files you'll want to edit the `config.ini` file to setup your server. This guide won't go in depth of every possible server setting, check the [OpenFusion GitHub Readme](https://github.com/OpenFusionProject/OpenFusion?tab=readme-ov-file#configuration) for more details on server configuration. + +The first section you might need to change is `login`. Note that by default the Login Server runs on port `23000`. If you plan on hosting both versions of the game, `academy` and `original` in the same machine, you have to use different ports for each of them. Make you sure pick ports that do not clash with other applications running on the same machine. +For example, you could have an `original` server running the Login Server on port `23000` and an `academy` server running on port `24000`. If you're planning to have just one version on the server, you can keep the default port. + +The next section you need to change is `shard`. The Shard Server uses the next port in the sequence, `23001` by default. If you're running two different versions of the server, you must also change this port to be unique for each. For example, `original` could run the Shard Server on port `23001` and `academy` on `24001`. + +The next important setting is `ip` in the `[shard]` section. This setting tells the launcher where to connect to your server after login. ++ **For a Local Network (LAN) Server:** Set this to the internal IP address of the server machine (e.g., `192.168.1.10`). ++ **For an Internet Server:** Set this to your public IP address or a domain name that points to it (e.g., `openfusion.mydomain.xyz`). + +Optionally you could also configure the `monitor` section if you need it to run on another port. Note that the `listenip` here is `127.0.0.1` and you should keep it, as the monitor server will look for the server in this same machine, so this is the correct address. + +After configuring the ports and IP address, you're good to move on to the next phase. If you want to further customize your settings this is a good time to do it. + +### Quick tip on hosting both versions + +If you plan on hosting both versions in the same machine, keep all their files organized so it's easy to tell the configuration files apart. A good directory structure to follow, especially when using a dedicated user, is to place all server-related files in `/opt/openfusion`. + +``` +/opt/openfusion/ +|-- academy +| |-- OpenFusionServer-Linux-Academy (server files) +| | `-- ... +| |-- ofapi (api files) +| | `-- ... +| |-- openfusion-academy.service (systemd service for server) +| `-- openfusionapi-academy.service (systemd service for api) +`-- original + |-- OpenFusionServer-Linux-Original + | `-- ... + |-- ofapi + | `-- ... + |-- openfusionapi-original.service + `-- openfusion-original.service +``` + +## Creating a dedicated user for the server + +If you're running the server on a Linux machine, it is highly recommended to run it under a dedicated, unprivileged user account. + +For this, create a new system group and user named `fusion`: +```bash +sudo groupadd --system fusion +sudo useradd --system -g fusion -d /opt/openfusion -s /bin/false fusion +``` +These commands create a `fusion` group and a `fusion` user. This user can't log in to a shell (`/bin/false`) and its home directory is set to `/opt/openfusion`. + +Next, create the directory structure and give the `fusion` user ownership of it: +```bash +sudo mkdir -p /opt/openfusion +sudo chown -R fusion:fusion /opt/openfusion +``` +Now you can move your server and API files into the appropriate directories inside `/opt/openfusion`, as shown in the structure above. For example, you would move your extracted `OpenFusionServer-Linux-Original` files into `/opt/openfusion/original/server/`. Remember to run `chown` again if you add new files as root. + +## Server service configuration + +If you're running the server on a Linux machine it's highly recommended to have a systemd service to manage the server process. +If you're on windows skip this step. +To do this, create a file in `/etc/systemd/system/` to configure the service. + +``` +sudo touch /etc/systemd/system/openfusion-.service +``` + +Change `` to `original` or `academy`, so you know exactly what service is for what server. Then edit the file with the following lines: + +``` +[Unit] +Description=Open Fusion Server - +After=network-online.target +Wants=network-online.target + +[Service] +WorkingDirectory=/opt/openfusion//server +ExecStart=/opt/openfusion//server/fusion +Restart=on-failure +RestartSec=10 +User=fusion +Group=fusion +Type=simple +TimeoutStartSec=300 +TimeoutStopSec=120 + +[Install] +WantedBy=multi-user.target +``` + +Make sure to replace `` with `original` or `academy`. The paths for `WorkingDirectory` and `ExecStart` now point to the standardized location we created. + +Note that the `ExecStart` line must end with `/fusion`, as this is the program that runs the OpenFusion server. + +To start the server you can now run: + +``` +sudo systemctl daemon reload +sudo systemctl enable openfusion-.service +sudo systemctl start openfusion-.service +``` + +## Hosting on a Local Network (LAN) + +If you wish for this server to be available only to players on your local network, you are good to go. All you need to do now is open the OpenFusion launcher on another computer on the same network and add a new server. + +The key difference from the solo launcher setup is that you'll configure the `Server Host` field with the internal IP address you set in the `shard` section of the `config.ini` file, and use the port you set in the `login` section. + +## Hosting on the Internet + +To make the server available for people all over the world to play it there are requirements you must meet first. + 1. Having a way to access this machine from any network. Be it via a static IP address or dynamic DNS. + 2. Setting up Port Forwarding for the machine + 3. Update `config.ini` with your public IP address or dynamic DNS as described previously. + +### Accessing the machine from any network + +If you're setting the server on a machine in your house chances are you do not have a static IP address. In that case you can either use a dynamic DNS service like No-IP, DuckDNS or Cloudflare API or contact your ISP for a static IP address. It is highly recommended that you create a DNS record for this IP address so it's easy to remember and share. + +For example, say you're running the server on a Linux machine in your house, and you have a static IP. You can create a DNS record like `openfusion.mydomain.xyz` to point to your public IP and access the server via that domain. Note that for this you need to acquire a domain. + +Once you have a way to talk to this machine from any network, you need to make sure that the ports you setup for the `login` and `shard` servers are open in this machine, and in your router if that's the case. Setting up port forwarding is different depending on your router model, whether you're using a VPS, etc, so make sure to look for a guide for your specific case here. The goal is to have the `login` and `shard` ports (`23000` and `23001` in this example) open. + +### Connecting to Your Server + +Once the server is running, you have a public domain or IP, and the ports are forwarded, you can connect to it from any computer on the internet. Open the launcher, add a new server, and use your public IP or domain for the `Server Host`, along with the `login` port. +For example: If your domain is `openfusion.mydomain.xyz` and your `login` server is running on port `23000`, set the `Server Host` field to `openfusion.mydomain.xyz:23000`. + +### Connecting from the Same Network (NAT Loopback) + +A common issue when hosting a server at home is that you might not be able to connect to it from a computer on the *same* network using its *public* IP address. Players from outside your network can connect just fine, but you can't. + +This happens because your router doesn't know how to route the traffic back into your own network. The solution is a feature called [NAT loopback (or NAT Hairpinning)](https://en.wikipedia.org/wiki/Network_address_translation#NAT_hairpinning). + +This guide will not go into details on how to configure this as it depends on your router and network setup, but searching for "how to enable NAT loopback on [your router model]" should give you the instructions you need. + +### Running Both Server Versions + +As mentioned in the [Understanding Server Versions](#understanding-server-versions) section, you can run both Original and Academy servers on the same machine. + +To do this, you'll need to follow the setup process twice: one for each version. This means you will have two separate sets of server files, two `config.ini` files (with different ports), and two systemd services. + +### Making an endpoint server + +At this point you have a fully working OpenFusion simple server, which you can access via the launcher using the IP address or domain for you server, and you'll have to login every time after connecting to the server. + +There's an improvement you can make to this setup so that you can have extra features, such as login memory, account management, monitoring and more. To do this, you'll need to add [OpenFusion API](https://github.com/OpenFusionProject/ofapi) to the server. This is an API (Application Programming Interface) that will communicate with the OpenFusion server to extended it's management features. + +*IMPORTANT*: To set OpenFusion API (OF API from now on) it is mandatory that you setup TLS for it, and it becomes a real risk if you don't have it secured with TLS. + +#### Getting started with OF API + +The first thing is to read the README of the project, [here](https://github.com/OpenFusionProject/ofapi), then download the code for OF API from the GitHub repository [here](https://github.com/OpenFusionProject/ofapi/tags). Download the latest version, extract it, and build the API executable with `cargo build --release`, this command will generate a binary in `./target/release/ofapi`. You'll also need to install a reverse proxy, like Nginx or Caddy, you can do this in the same machine or in another one. + +Once you have the program built, you'll want to change the `config.toml` file to configure it according to your server setup. +You must enable (uncomment) the `core` and `game` sections, and those must be configured properly. It is also recommended that you enable and configure the `monitor` section, so the launcher can report how many players are online to the users. + +Keep in mind that if you have OF API setup you won't need a domain that points directly to your OpenFusion server, as OF API will handle it for you, so your domain should point to OF API instead. You'll still need the OpenFusion server ports open. + +#### Configuring OF API + +This is pretty straight forward, in the `config.toml` file, you'll need to adjust several sections. + +##### [core] + +Set `server_name` to whatever you'd like to name your server, and `public_url` to your server's domain (the one you set up with DNS records). For `db_path`, use the path to the `database.db` file in your OpenFusion server folder. If you followed the recommended directory structure, this will be something like `../OpenFusionServer-Linux-Academy/database.db`. Set `templates_dir` to `./templates`. + +The `port` setting determines which port OF API will listen on for unencrypted HTTP traffic. You can set this to any port that doesn't clash with other applications, for example `8888`. + +For `bind_ip`, you'll use `0.0.0.0` if your proxy is running in another machine, or `127.0.0.1` if your proxy is running in the same machine as OF API. We'll talk more about proxy configuration in a moment. + +##### [tls] + +This section is for handling encrypted HTTPS traffic. It must be enabled if you plan on exposing the server to the public, and you can handle TLS through a proxy or through OF API itselft. This guide will describe how to handle TLS via a proxy, like Nginx or Caddy. + +The important setting here is the `port`, which must be set to a port that is not used by any other application. To keep things easy to remember, it's recommended to set this to `4433`, as the default SSL port is `443`, but you can use any port you like. + +If you're using a proxy to handle TLS, you can leave `cert_path` and `key_path` with placeholder values like `cert.pem`. + +##### [game] + +In the `game` section you have to set the `versions` list with the UUID for the versions that your server supports. You can find the correct UUIDs in the [Understanding Server Versions](#understanding-server-versions) section near the top of this guide. + +For `login_address` you'll set your server's domain and the port that you configured for the login server, for example `openfusion.mydomain.xyz:23000`. + +##### [monitor] + +In the `monitor` section, keep `route = "/status"` and make sure that `monitor_ip` is set to the IP and port of the machine running the OpenFusion server. Since it's the same machine, use `127.0.0.1` and the port you set in the server's `config.ini` for the monitor service. For example `monitor_ip = "127.0.0.1:8003"`. + +##### [account] + +In the `account` section you'll configure how to manage accounts, such as if email verification is required. This will depend on how you want to manage your server, so feel free to set it up however you like. Pay special attention to the `account_level` setting, as that will determine the permission level for new accounts. + +``` +# account permission level that will be set upon character creation +1 = default, will allow *all* commands +30 = allow some more "abusable" commands such as /summon +50 = only allow cheat commands, like /itemN and /speed +99 = standard user account, no cheats allowed +any number higher than 50 will disable commands +``` + +##### [auth] + +In the `auth` section you can leave the settings as is, except for `secret_path`. It's recommended to use a random string of numbers and letters to keep your server secure. You can generate a random string in Linux with the following command: `echo $(date +%s | sha256sum | base64 | head -c 32)`. + +Here's an example `config.toml` file for OF API: +``` +[core] +server_name = "My OpenFusion Server" +public_url = "openfusion.myserver.xyz" +db_path = "../OpenFusionServer-Linux-Academy/database.db" +template_dir = "./templates" +bind_ip="0.0.0.0" +port = 8888 + +[tls] +cert_path = "cert.pem" # app-level TLS only +key_path = "key.pem" # app-level TLS only +port = 4433 + +[game] +versions = ["6543a2bb-d154-4087-b9ee-3c8aa778580a"] +login_address = "openfusion.myserver.xyz:24000" +custom_loading_screen = false + +[monitor] +route = "/status" +monitor_ip = "127.0.0.1:8003" + +[moderation] +namereq_route = "/namereq" + +[rankinfo] +route = "/getranks" +placeholders = true + +[account] +route = "/account" + +register_subroute = "/register" +account_level = 99 +require_email = false +require_email_verification = false + +email_verification_subroute = "/verify" +email_verification_valid_secs = 3_600 # one hour + +update_email_subroute = "/update/email" +update_password_subroute = "/update/password" + +temporary_password_subroute = "/otp" +temporary_password_valid_secs = 3_600 # one hour + +[auth] +route = "/auth" +refresh_subroute = "/session" +secret_path = "ZWQzYjFiYzZjM2YyZThhYjRmMjM0Y2M1" +valid_secs_refresh = 604_800 # one week +valid_secs_session = 900 # 15 minutes + +[cookie] +route = "/cookie" +valid_secs = 60 + +[legacy] +index_route = "/index.html" +assetinfo_route = "/assetInfo.php" +logininfo_route = "/loginInfo.php" +``` + +With the configuration set you can now start the OF API server, if you are on Linux it's recommended to create a systemd service for it, as described in [Server service configuration](#Server-service-configuration). The difference is that this service will execute OF API instead of the OpenFusion server. You can use this as a template, remember to change the placeholders as described previously: + +``` +[Unit] +Description=Open Fusion API - +After=network-online.target +Wants=network-online.target + +[Service] +WorkingDirectory=/opt/openfusion//ofapi +ExecStart=/opt/openfusion//ofapi/target/release/ofapi +Restart=on-failure +RestartSec=10 +User=fusion +Group=fusion +Type=simple +TimeoutStartSec=300 +TimeoutStopSec=120 + +[Install] +WantedBy=multi-user.target +``` + +#### Configuring a Proxy for OF API + +Now that you have OF API up and running, you need to setup a reverse proxy to route traffic to it. A reverse proxy acts as a gateway between the internet and your OF API service. It can handle incoming web traffic and forward it to the correct application port on your server. This is where TLS will be handled for OF API. + +Your proxy will listen on the standard web ports (80 for HTTP and 443 for HTTPS) and forward that traffic to the ports you configured in OF API's `config.toml` file (e.g., 8888 for HTTP and 4433 for HTTPS). + +*IMPORTANT* If your proxy is running on a different machine, make sure you set `bind_ip="0.0.0.0"` in OF API's config. If the proxy is on the same machine, use `bind_ip="127.0.0.1"`. + +The configuration for the reverse proxy is pretty simple. You'll set it up for the domain you've pointed to OF API (the `public_url` in `config.toml`) and have it forward requests to the machine running OF API. + +*IMPORTANT:* If you're running both OpenFusion versions in the same machine, you'll have to do this twice, once for each OF API instance. This means you'll need two different domains (e.g., `academy.mydomain.xyz` and `original.mydomain.xyz`) and two proxy configurations, each pointing to the correct ports for its corresponding OF API instance. + +##### Setting up Nginx + +1. Install Nginx +2. Create `/etc/nginx/sites-available/openfusionapi-.conf` nginx config following the template bellow +3. Enable the nginx configuration with this command: `ln -s /etc/nginx/sites-available/openfusionapi-.conf /etc/nginx/sites-enabled/` +4. Acquire a SSL certificate. You can do this via a Cloudflare DNS Challenge or [Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04) for example + +Nginx example configuration, remember to change the placeholders. *Note:* If you plan on using Let's Encrypt for your certificate, you might want to use the `default.conf` template in `/etc/nginx/sites-available` for this, because when you run `certbot` to get the certificates it will automatically update your Nginx configuration files. +```nginx +# /etc/nginx/sites-available/openfusionapi-.conf + +# This server block listens for standard HTTP traffic on port 80 +# and forwards it to the port you configured for OF API's HTTP interface. +server { + listen 80; + listen [::]:80; + + server_name ; # Domain you pointed to OF API, should be the same as `public_url` in of api's config + + location / { + # Forward the request to the of api + proxy_pass http://:8888; # OF API ip address and the HTTP port from config.toml + + # --- Standard Proxy Headers --- + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} + +# This server block listens for standard HTTPS traffic on port 443 +# and forwards it to the port you configured for OF API's TLS interface. +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name ; # same as above + + # --- SSL Configuration --- + # These paths point to the certificates you acquired. + ssl_certificate /etc/letsencrypt/live//fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live//privkey.pem; + + location / { + # Forward the request to the of api's TLS port + proxy_pass http://:4433; # OF API ip address and the TLS port from config.toml + + # --- Standard Proxy Headers --- + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # --- WebSocket Support --- + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +``` + +Here's an example for another popular tool, Caddy, using Cloudflare's DNS challenge for SSL: + +```caddy +# HTTP traffic on port 80 proxies to port 8888 +http://openfusion-api.mydomain.xyz { + log + reverse_proxy :8888 +} + +# HTTPS traffic on port 443 proxies to port 4433 +openfusion-api.mydomain.xyz { + log + tls { + dns cloudflare + } + reverse_proxy :4433 +} +``` + +With OF API and it's OpenFusion server up and running you can now open the launcher and connect to your endpoint server using the `public_url` you configured in `config.toml`. +{{< figure + src="images/2.0-launcher-adding-endpoint.png" + alt="Adding a simple server" +>}} diff --git a/static/openfusion-server-bootstrapper.sh b/static/openfusion-server-bootstrapper.sh new file mode 100644 index 0000000..9b3a4a9 --- /dev/null +++ b/static/openfusion-server-bootstrapper.sh @@ -0,0 +1,892 @@ +#!/usr/bin/env sh + +########################################### +# Global Variables +########################################### + +# Server version constants +VERSION_ORIGINAL="original" +VERSION_ACADEMY="academy" + +# UUIDs for API configuration +UUID_ORIGINAL="ec8063b2-54d4-4ee1-8d9e-381f5babd420" +UUID_ACADEMY="6543a2bb-d154-4087-b9ee-3c8aa778580a" + +# Base installation directory +BASE_DIR="/opt/openfusion" + +# Temporary build directory for ofapi +OFAPI_BUILD_DIR="/tmp/ofapi-build" + +# Variables to be set by user input +INSTALL_ORIGINAL=0 +INSTALL_ACADEMY=0 +SERVER_TYPE="" # "simple" or "endpoint" +SERVER_NAME="" +ACCOUNT_LEVEL=99 + +########################################### +# Utils +########################################### + +# Print ASCII art header +print_ascii_header() { + cat << 'EOF' + ___ ______ _ + / _ \ _ __ ___ _ __ | ____| (_) + | | | | '_ \ / _ \ '_ \| |__ _ _ ___ _ ___ _ __ + | | | | |_) | __/ | | | __| | | / __| |/ _ \| '_ \ + | |_| | .__/ \___|_| |_| | | |_| \__ \ | (_) | | | | + \___/|_| |_| \__,_|___/_|\___/|_| |_| + +EOF +} + +# Color codes for terminal output +COLOR_RED='\033[0;31m' +COLOR_GREEN='\033[0;32m' +COLOR_BLUE='\033[0;34m' +COLOR_CYAN='\033[0;36m' +COLOR_YELLOW='\033[1;33m' +COLOR_RESET='\033[0m' + +# Print a header with color +print_header() { + echo "" + printf "${COLOR_CYAN}==========================================\n" + printf "%s\n" "$1" + printf "==========================================${COLOR_RESET}\n" +} + +# Print an error message and exit +print_error() { + printf "${COLOR_RED}[ERROR]${COLOR_RESET} %s\n" "$1" + exit 1 +} + +# Print a success message +print_success() { + printf "${COLOR_GREEN}[OK]${COLOR_RESET} %s\n" "$1" +} + +# Print a warning message +print_warning() { + printf "${COLOR_YELLOW}[WARNING]${COLOR_RESET} %s\n" "$1" +} + +# Check if a command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Check all requirements including root access and dependencies +check_requirements() { + # Check if the user is root + if [ "$(id -u)" -ne 0 ]; then + print_error "This script must be run as root\nPlease run: sudo $0" + fi + + print_header "Checking Dependencies" + + local missing_deps="" + local version_issues="" + + for cmd in wget unzip curl; do + if ! command_exists "$cmd"; then + missing_deps="$missing_deps $cmd" + else + print_success "$cmd is installed" + fi + done + + + # Check GLIBC version (required: 2.38 or higher) + echo "Checking system library versions..." + if command_exists "ldd"; then + local glibc_version=$(ldd --version 2>&1 | head -n 1 | grep -oE '[0-9]+\.[0-9]+' | head -n 1) + if [ -n "$glibc_version" ]; then + # Convert version to comparable integer (e.g., 2.38 -> 238) + local glibc_major=$(echo "$glibc_version" | cut -d. -f1) + local glibc_minor=$(echo "$glibc_version" | cut -d. -f2) + local glibc_ver_int=$((glibc_major * 100 + glibc_minor)) + + if [ "$glibc_ver_int" -lt 238 ]; then + version_issues="${version_issues}\n - GLIBC version $glibc_version found, but 2.38 or higher is required" + print_warning "GLIBC $glibc_version (need 2.38+)" + else + print_success "GLIBC $glibc_version" + fi + fi + fi + + # Check GLIBCXX version (required: 3.4.32 or higher) + if [ -f "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" ] || [ -f "/usr/lib64/libstdc++.so.6" ]; then + local libstdc_path="/usr/lib/x86_64-linux-gnu/libstdc++.so.6" + if [ ! -f "$libstdc_path" ]; then + libstdc_path="/usr/lib64/libstdc++.so.6" + fi + + # Check if GLIBCXX_3.4.32 is available + if strings "$libstdc_path" 2>/dev/null | grep -q "GLIBCXX_3.4.32"; then + print_success "GLIBCXX 3.4.32+ available" + else + # Get the highest version available + local highest_glibcxx=$(strings "$libstdc_path" 2>/dev/null | grep "GLIBCXX_3.4" | sort -V | tail -n 1) + version_issues="${version_issues}\n - GLIBCXX_3.4.32 not found (found: $highest_glibcxx)" + print_warning "GLIBCXX $highest_glibcxx (need 3.4.32+)" + fi + else + version_issues="${version_issues}\n - libstdc++.so.6 not found" + print_warning "libstdc++.so.6 not found" + fi + + # Exit if any dependencies are missing + if [ -n "$missing_deps" ]; then + print_error "Missing required dependencies:$missing_deps\nPlease install them and run this script again." + fi + + # Warn about version issues but don't exit (user might be checking before upgrading) + if [ -n "$version_issues" ]; then + echo "" + printf "${COLOR_YELLOW}[WARNING] System library version issues detected:${COLOR_RESET}\n" + printf "${version_issues}\n" + echo "" + echo "OpenFusion server requires:" + echo " - GLIBC 2.38 or higher" + echo " - GLIBCXX 3.4.32 or higher" + echo "" + echo "The server binary will not run without these versions." + echo "Consider upgrading your system or using a newer distribution." + echo "" + printf "Do you want to continue anyway? (y/N): " + read -r continue_choice + case "$continue_choice" in + [Yy]|[Yy][Ee][Ss]) + print_warning "Continuing despite version issues..." + ;; + *) + echo "Setup cancelled." + exit 1 + ;; + esac + fi + + print_success "All dependencies are satisfied" +} + +########################################### +# User Prompts +########################################### + +prompt_version_selection() { + print_header "Server Version Selection" + + echo "Which version(s) would you like to install?" + echo "1) Original" + echo "2) Academy" + echo "3) Both" + echo "" + + # Loop until valid choice is made + while true; do + printf "Enter your choice [1-3]: " + read -r version_choice + + case "$version_choice" in + 1) + INSTALL_ORIGINAL=1 + print_success "Installing: Original" + break + ;; + 2) + INSTALL_ACADEMY=1 + print_success "Installing: Academy" + break + ;; + 3) + INSTALL_ORIGINAL=1 + INSTALL_ACADEMY=1 + print_success "Installing: Both Original and Academy" + break + ;; + *) + print_warning "Invalid choice. Please enter 1, 2, or 3." + ;; + esac + done +} + +prompt_server_type() { + print_header "Server Type Selection" + + echo "What type of server would you like to setup?" + echo "1) Simple Server (basic server, no API)" + echo "2) Endpoint Server (with OpenFusion API for account management)" + echo "" + + # Loop until valid choice is made + while true; do + printf "Enter your choice [1-2]: " + read -r type_choice + + case "$type_choice" in + 1) + SERVER_TYPE="simple" + print_success "Server type: Simple" + break + ;; + 2) + SERVER_TYPE="endpoint" + + # Check for cargo if endpoint server is selected + if [ "$SERVER_TYPE" = "endpoint" ]; then + if ! command_exists "cargo"; then + print_error "cargo is not installed but is required for endpoint servers.\nPlease install Rust and Cargo from https://rustup.rs/ and run this script again." + exit 1 + else + print_success "Server type: Endpoint (with API)" + fi + fi + break + ;; + *) + print_warning "Invalid choice. Please enter 1 or 2." + ;; + esac + done +} + +prompt_server_info() { + print_header "Server Configuration" + + # Prompt for server name if endpoint server + if [ "$SERVER_TYPE" = "endpoint" ]; then + printf "Enter server name (e.g., 'My OpenFusion Server'): " + read -r SERVER_NAME + if [ -z "$SERVER_NAME" ]; then + SERVER_NAME="OpenFusion Server" + fi + print_success "Server name: $SERVER_NAME" + fi + + # Prompt for account level + echo "" + echo "Account permission levels:" + echo " 1 = Allow ALL commands" + echo " 30 = Allow some 'abusable' commands like /summon" + echo " 50 = Only allow cheat commands like /itemN and /speed" + echo " 99 = Standard user account, no cheats (RECOMMENDED)" + echo "" + printf "Enter account level [99]: " + read -r ACCOUNT_LEVEL + if [ -z "$ACCOUNT_LEVEL" ]; then + ACCOUNT_LEVEL=99 + fi + print_success "Account level: $ACCOUNT_LEVEL" +} + +########################################### +# User & Directory Setup +########################################### + +setup_user_and_directories() { + print_header "Setting Up User and Directories" + + # Create fusion group if it doesn't exist + if ! getent group fusion >/dev/null 2>&1; then + groupadd --system fusion + print_success "Created fusion group" + else + print_success "fusion group already exists" + fi + + # Create fusion user if it doesn't exist + if ! id -u fusion >/dev/null 2>&1; then + useradd --system -g fusion -d "$BASE_DIR" -s /bin/false fusion + print_success "Created fusion user" + else + print_success "fusion user already exists" + fi + + # Create base directory + mkdir -p "$BASE_DIR" + print_success "Created $BASE_DIR" + + # Create directories for selected versions + if [ "$INSTALL_ORIGINAL" -eq 1 ]; then + mkdir -p "$BASE_DIR/original" + print_success "Created $BASE_DIR/original" + fi + + if [ "$INSTALL_ACADEMY" -eq 1 ]; then + mkdir -p "$BASE_DIR/academy" + print_success "Created $BASE_DIR/academy" + fi + + # Set ownership + chown -R fusion:fusion "$BASE_DIR" + print_success "Set ownership to fusion:fusion" +} + +########################################### +# Server File Download & Extraction +########################################### + +download_and_extract_server() { + local version=$1 + local version_dir="$BASE_DIR/$version" + + print_header "Downloading OpenFusion Server - $version" + + # Get latest release information from GitHub API + echo "Fetching latest release information..." + local release_json + release_json=$(curl -s https://api.github.com/repos/OpenFusionProject/OpenFusion/releases/latest) + + if [ -z "$release_json" ]; then + print_error "Failed to fetch release information from GitHub" + fi + + # Determine the correct asset name based on version + local asset_name + if [ "$version" = "$VERSION_ORIGINAL" ]; then + asset_name="OpenFusionServer-Linux-Original.zip" + else + asset_name="OpenFusionServer-Linux-Academy.zip" + fi + + # Extract download URL for the specific asset + local download_url + download_url=$(echo "$release_json" | grep -o "\"browser_download_url\":[[:space:]]*\"[^\"]*$asset_name\"" | grep -o 'https://[^"]*') + + if [ -z "$download_url" ]; then + print_error "Could not find download URL for $asset_name" + fi + + print_success "Found download URL" + + # Download the server files + echo "Downloading $asset_name..." + local temp_file="/tmp/$asset_name" + if ! wget -q --show-progress -O "$temp_file" "$download_url"; then + print_error "Failed to download server files" + fi + print_success "Downloaded server files" + + # Extract to the version directory + echo "Extracting server files..." + mkdir -p "$version_dir/server" + if ! unzip -q "$temp_file" -d "$version_dir/server"; then + print_error "Failed to extract server files" + fi + + # Move files up one level if they were extracted into a subdirectory + local extracted_dir=$(find "$version_dir/server" -mindepth 1 -maxdepth 1 -type d | head -n 1) + if [ -n "$extracted_dir" ]; then + mv "$extracted_dir"/* "$version_dir/server/" 2>/dev/null || true + rmdir "$extracted_dir" 2>/dev/null || true + fi + + chmod +x "$version_dir/server/fusion" + + print_success "Extracted server files to $version_dir/server" + + # Clean up + rm "$temp_file" + + # Set ownership + chown -R fusion:fusion "$version_dir" +} + +########################################### +# Server Configuration +########################################### + +configure_server_ini() { + local version=$1 + local config_file="$BASE_DIR/$version/server/config.ini" + + print_header "Configuring Server - $version" + + if [ ! -f "$config_file" ]; then + print_error "Config file not found: $config_file" + fi + + # Set ports based on version + local login_port shard_port monitor_port + if [ "$version" = "$VERSION_ORIGINAL" ]; then + login_port=23000 + shard_port=23001 + monitor_port=8003 + else + login_port=24000 + shard_port=24001 + monitor_port=8004 + fi + + # Backup original config + cp "$config_file" "$config_file.backup" + + # Update login port (POSIX compliant sed) + sed "s/^port[[:space:]]*=.*/port=$login_port/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + print_success "Set login port to $login_port" + + # Update shard port and IP (POSIX compliant sed) + # Find the [shard] section and update the port + sed "/^\[shard\]/,/^\[/ s/^port[[:space:]]*=.*/port=$shard_port/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + print_success "Set shard port to $shard_port" + + # Update shard IP (using 127.0.0.1 as default) + sed "/^\[shard\]/,/^\[/ s/^ip[[:space:]]*=.*/ip=127.0.0.1/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + print_success "Set shard IP to 127.0.0.1 (change this for network access)" + + # Update monitor port + sed "/^\[monitor\]/,/^\[/ s/^port[[:space:]]*=.*/port=$monitor_port/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + print_success "Set monitor port to $monitor_port" + + # Update account level + sed "/^\[account\]/,/^\[/ s/^defaultaccountlevel[[:space:]]*=.*/defaultaccountlevel=$ACCOUNT_LEVEL/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + print_success "Set default account level to $ACCOUNT_LEVEL" + + print_success "Configuration complete" +} + +########################################### +# Endpoint Server Setup +########################################### + +build_ofapi_once() { + print_header "Building OpenFusion API" + + # Download ofapi + # Latest tag not available here, so version is hardcoded + local ofapi_url="https://github.com/OpenFusionProject/ofapi/archive/refs/tags/v1.0.1.tar.gz" + local temp_file="/tmp/ofapi-1.0.1.tar.gz" + + echo "Downloading OpenFusion API..." + if ! wget -q --show-progress -O "$temp_file" "$ofapi_url"; then + print_error "Failed to download OpenFusion API" + fi + print_success "Downloaded OpenFusion API" + + # Extract ofapi to temporary build directory + echo "Extracting OpenFusion API..." + mkdir -p "$OFAPI_BUILD_DIR" + if ! tar -xzf "$temp_file" -C "$OFAPI_BUILD_DIR" --strip-components=1; then + print_error "Failed to extract OpenFusion API" + fi + print_success "Extracted OpenFusion API" + + # Clean up tarball + rm "$temp_file" + + # Build ofapi (only once!) + echo "Building OpenFusion API (this may take a few minutes)..." + cd "$OFAPI_BUILD_DIR" || print_error "Failed to change to build directory" + + if ! cargo build --release 2>&1; then + print_error "Failed to build OpenFusion API" + fi + print_success "Built OpenFusion API binary" + + # Return to original directory + cd - >/dev/null || true +} + +setup_ofapi_for_version() { + local version=$1 + local version_dir="$BASE_DIR/$version" + + print_header "Setting up OpenFusion API - $version" + + # Create ofapi directory for this version + mkdir -p "$version_dir/ofapi" + + # Copy the built binary + echo "Copying ofapi binary..." + cp "$OFAPI_BUILD_DIR/target/release/ofapi" "$version_dir/ofapi/" + print_success "Copied binary to $version_dir/ofapi/" + + # Copy necessary files (templates, config.toml) + echo "Copying configuration files..." + if [ -d "$OFAPI_BUILD_DIR/templates" ]; then + cp -r "$OFAPI_BUILD_DIR/templates" "$version_dir/ofapi/" + print_success "Copied templates directory" + fi + + if [ -f "$OFAPI_BUILD_DIR/config.toml" ]; then + cp "$OFAPI_BUILD_DIR/config.toml" "$version_dir/ofapi/" + print_success "Copied config.toml" + fi + + if [ -f "$OFAPI_BUILD_DIR/statics.csv" ]; then + cp "$OFAPI_BUILD_DIR/statics.csv" "$version_dir/ofapi/" + print_success "Copied statics.csv" + fi + + # Set ownership + chown -R fusion:fusion "$version_dir/ofapi" + + print_success "OpenFusion API setup complete for $version" +} + +configure_ofapi_toml() { + local version=$1 + local version_dir="$BASE_DIR/$version" + local config_file="$version_dir/ofapi/config.toml" + + print_header "Configuring OpenFusion API - $version" + + # Set ports and addresses based on version + local http_port tls_port login_port monitor_port uuid + if [ "$version" = "$VERSION_ORIGINAL" ]; then + http_port=8888 + tls_port=4433 + login_port=23000 + monitor_port=8003 + uuid="$UUID_ORIGINAL" + else + http_port=9999 + tls_port=5544 + login_port=24000 + monitor_port=8004 + uuid="$UUID_ACADEMY" + fi + + # Generate random auth secret + local auth_secret + auth_secret=$(date +%s | sha256sum | base64 | head -c 32) + + # Backup original config + cp "$config_file" "$config_file.backup" + + # Update config.toml using sed (POSIX compliant) + # Escape special characters in variables for sed + local uuid_escaped=$(echo "$uuid" | sed 's/[\/&]/\\&/g') + local secret_escaped=$(echo "$auth_secret" | sed 's/[\/&]/\\&/g') + local server_name_escaped=$(echo "$SERVER_NAME" | sed 's/[\/&]/\\&/g') + + # Update [core] section + sed "s/^server_name[[:space:]]*=.*/server_name = \"$server_name_escaped\"/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + sed "s/^public_url[[:space:]]*=.*/public_url = \"localhost\"/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + sed "s|^db_path[[:space:]]*=.*|db_path = \"..\/server\/database.db\"|" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + sed "s/^bind_ip[[:space:]]*=.*/bind_ip = \"127.0.0.1\"/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + sed "/^\[core\]/,/^\[/ s/^port[[:space:]]*=.*/port = $http_port/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + + # Update [tls] section + sed "/^\[tls\]/,/^\[/ s/^port[[:space:]]*=.*/port = $tls_port/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + + # Update [game] section + sed "/^\[game\]/,/^\[/ s/^versions[[:space:]]*=.*/versions = [\"$uuid_escaped\"]/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + sed "/^\[game\]/,/^\[/ s/^login_address[[:space:]]*=.*/login_address = \"localhost:$login_port\"/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + + # Update [monitor] section + sed "/^\[monitor\]/,/^\[/ s/^monitor_ip[[:space:]]*=.*/monitor_ip = \"127.0.0.1:$monitor_port\"/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + + # Update [account] section + sed "/^\[account\]/,/^\[/ s/^account_level[[:space:]]*=.*/account_level = $ACCOUNT_LEVEL/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + + # Update [auth] section - secret_path + sed "/^\[auth\]/,/^\[/ s/^secret_path[[:space:]]*=.*/secret_path = \"$secret_escaped\"/" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" + + print_success "Configured config.toml" + print_success "HTTP port: $http_port, TLS port: $tls_port" + + # Set ownership + chown fusion:fusion "$config_file" +} + +########################################### +# Systemd Service Creation +########################################### + +create_server_service() { + local version=$1 + local service_file="$BASE_DIR/$version/openfusion-$version.service" + local systemd_link="/etc/systemd/system/openfusion-$version.service" + + print_header "Creating Systemd Service - openfusion-$version" + + # Create service file in base directory + cat > "$service_file" << EOF +[Unit] +Description=OpenFusion Server - $version +After=network-online.target +Wants=network-online.target + +[Service] +WorkingDirectory=$BASE_DIR/$version/server +ExecStart=$BASE_DIR/$version/server/fusion +Restart=on-failure +RestartSec=10 +User=fusion +Group=fusion +Type=simple +TimeoutStartSec=300 +TimeoutStopSec=120 + +[Install] +WantedBy=multi-user.target +EOF + + # Set ownership + chown fusion:fusion "$service_file" + + # Create symlink to systemd directory + ln -sf "$service_file" "$systemd_link" + + print_success "Created service file and symlinked to systemd" +} + +create_ofapi_service() { + local version=$1 + local service_file="$BASE_DIR/$version/openfusionapi-$version.service" + local systemd_link="/etc/systemd/system/openfusionapi-$version.service" + + print_header "Creating Systemd Service - openfusionapi-$version" + + # Create service file in base directory + cat > "$service_file" << EOF +[Unit] +Description=OpenFusion API - $version +After=network-online.target +Wants=network-online.target + +[Service] +WorkingDirectory=$BASE_DIR/$version/ofapi +ExecStart=$BASE_DIR/$version/ofapi/ofapi +Restart=on-failure +RestartSec=10 +User=fusion +Group=fusion +Type=simple +TimeoutStartSec=300 +TimeoutStopSec=120 + +[Install] +WantedBy=multi-user.target +EOF + + # Set ownership + chown fusion:fusion "$service_file" + + # Create symlink to systemd directory + ln -sf "$service_file" "$systemd_link" + + print_success "Created service file and symlinked to systemd" +} + +########################################### +# Final Instructions +########################################### + +print_final_instructions() { + print_header "Installation Complete!" + + echo "" + echo "SUMMARY:" + echo "--------" + + if [ "$INSTALL_ORIGINAL" -eq 1 ]; then + echo "✓ Installed OpenFusion Original" + echo " - Server directory: $BASE_DIR/original/server" + echo " - Config file: $BASE_DIR/original/server/config.ini" + echo " - Login port: 23000, Shard port: 23001" + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo " - API directory: $BASE_DIR/original/ofapi" + echo " - API config: $BASE_DIR/original/ofapi/config.toml" + echo " - API HTTP port: 8888, TLS port: 4433" + fi + fi + + if [ "$INSTALL_ACADEMY" -eq 1 ]; then + echo "✓ Installed OpenFusion Academy" + echo " - Server directory: $BASE_DIR/academy/server" + echo " - Config file: $BASE_DIR/academy/server/config.ini" + echo " - Login port: 24000, Shard port: 24001" + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo " - API directory: $BASE_DIR/academy/ofapi" + echo " - API config: $BASE_DIR/academy/ofapi/config.toml" + echo " - API HTTP port: 9999, TLS port: 5544" + fi + fi + + echo "" + echo "NEXT STEPS:" + echo "-----------" + echo "" + echo "1. Configure IP Address:" + echo " Edit the config.ini file(s) and change the 'ip' setting in the [shard]" + echo " section to:" + echo " - Your local network IP for LAN access" + echo " - Your public IP or domain for internet access" + echo "" + + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo "2. Configure API Domain:" + echo " Edit the config.toml file(s) and change 'public_url' and 'login_address'" + echo " to your actual domain or IP address" + echo "" + echo "3. Setup Reverse Proxy (Nginx/Caddy) with TLS/SSL certificates" + echo " This is REQUIRED for endpoint servers!" + echo " See the guide: https://openfusionproject.github.io/docs/guides/setting-up-your-own-server/" + echo "" + fi + + local step_num=2 + if [ "$SERVER_TYPE" = "endpoint" ]; then + step_num=4 + fi + + echo "$step_num. Open Firewall Ports:" + echo " Make sure the following ports are open in your firewall and router:" + if [ "$INSTALL_ORIGINAL" -eq 1 ]; then + echo " - Original: 23000 (login), 23001 (shard)" + fi + if [ "$INSTALL_ACADEMY" -eq 1 ]; then + echo " - Academy: 24000 (login), 24001 (shard)" + fi + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo " - HTTP: 80, HTTPS: 443 (for reverse proxy)" + fi + echo "" + + step_num=$((step_num + 1)) + echo "$step_num. Start the Services:" + echo " After completing the configuration, run these commands:" + echo "" + echo " systemctl daemon-reload" + + if [ "$INSTALL_ORIGINAL" -eq 1 ]; then + echo " systemctl enable openfusion-original.service" + echo " systemctl start openfusion-original.service" + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo " systemctl enable openfusionapi-original.service" + echo " systemctl start openfusionapi-original.service" + fi + fi + + if [ "$INSTALL_ACADEMY" -eq 1 ]; then + echo " systemctl enable openfusion-academy.service" + echo " systemctl start openfusion-academy.service" + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo " systemctl enable openfusionapi-academy.service" + echo " systemctl start openfusionapi-academy.service" + fi + fi + + echo "" + step_num=$((step_num + 1)) + echo "$step_num. Check Service Status:" + echo " systemctl status openfusion-*" + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo " systemctl status openfusionapi-*" + fi + + echo "" + echo "For more information, see the complete guide at:" + echo "https://openfusionproject.github.io/docs/guides/setting-up-your-own-server/" + echo "" +} + +########################################### +# Main Flow: Initial Server Setup +########################################### + +initial_server_setup() { + # Check requirements first (includes root check and dependencies) + check_requirements + + prompt_version_selection + prompt_server_type + prompt_server_info + + setup_user_and_directories + + # Build ofapi once if endpoint server is selected + if [ "$SERVER_TYPE" = "endpoint" ]; then + build_ofapi_once + fi + + # Setup Original version if selected + if [ "$INSTALL_ORIGINAL" -eq 1 ]; then + download_and_extract_server "$VERSION_ORIGINAL" + configure_server_ini "$VERSION_ORIGINAL" + + if [ "$SERVER_TYPE" = "endpoint" ]; then + setup_ofapi_for_version "$VERSION_ORIGINAL" + configure_ofapi_toml "$VERSION_ORIGINAL" + fi + + create_server_service "$VERSION_ORIGINAL" + if [ "$SERVER_TYPE" = "endpoint" ]; then + create_ofapi_service "$VERSION_ORIGINAL" + fi + fi + + # Setup Academy version if selected + if [ "$INSTALL_ACADEMY" -eq 1 ]; then + download_and_extract_server "$VERSION_ACADEMY" + configure_server_ini "$VERSION_ACADEMY" + + if [ "$SERVER_TYPE" = "endpoint" ]; then + setup_ofapi_for_version "$VERSION_ACADEMY" + configure_ofapi_toml "$VERSION_ACADEMY" + fi + + create_server_service "$VERSION_ACADEMY" + if [ "$SERVER_TYPE" = "endpoint" ]; then + create_ofapi_service "$VERSION_ACADEMY" + fi + fi + + # Clean up temporary build directory + if [ "$SERVER_TYPE" = "endpoint" ]; then + echo "" + echo "Cleaning up temporary build files..." + rm -rf "$OFAPI_BUILD_DIR" + print_success "Cleanup complete" + fi + + print_final_instructions +} + +########################################### +# Usage Information +########################################### + +show_usage() { + echo "Usage: $0 [OPTIONS]" + echo "" + echo "OpenFusion Server Bootstrapper - Automated server setup" + echo "" + echo "Options:" + echo " --help, -h Show this help message" + echo "" +} + +########################################### +# Script Entry Point +########################################### + +clear +printf "${COLOR_CYAN}" +print_ascii_header +printf "${COLOR_RESET}\n" +echo " Automated Server Setup for OpenFusion" +echo "" +check_requirements + +# Parse command line arguments +if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then + show_usage + exit 0 +elif [ -n "$1" ]; then + echo "Error: Unknown option '$1'" + echo "" + show_usage + exit 1 +else + # Default: Run initial server setup + initial_server_setup +fi