Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ db.sqlite3
*.egg-info/
.vscode/
.idea/
.DS_Store
.DS_Store
tmp/
AGENTS.md
.venv/
# dev TLS
certs/*.pem
675 changes: 675 additions & 0 deletions COPYING.md

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Satisfactory Solver – Web App

## Overview

Satisfactory Solver is a Django + Pyomo web application that optimizes factory layouts for the game *Satisfactory*. It allows players to define resource limits, recipe availability, item inputs/outputs, and weighting factors, then automatically computes the optimal production plan using linear optimization.

The web interface is built in vanilla HTML, CSS, and JavaScript (see `index.html`) and communicates with the backend API endpoints for metadata, optimization, and user-saved presets.

## Main Features

- Dynamic browser UI with multiple tabs:
- Resources: configure resource availability limits
- Weights: set optimization weight factors
- Inputs/Outputs: define items and desired outputs
- Recipes: toggle alternate recipes on/off
- Results: display optimization results and statistics
- Pyomo-based backend optimizer using the HiGHS solver
- User authentication and saved presets:
- Users can create accounts, log in/out, and save/load/delete named optimization settings
- JSON-based data model for items, recipes, and resources
- Integrated Django Admin for managing Default and Saved settings

## Project Structure

| Path | Purpose |
| --------------------- | ----------------------------------------------- |
| `ui/index.html` | Main single-page interface |
| `ui/views.py` | Django views and API endpoints |
| `ui/models.py` | `DefaultSettings` and `SavedSettings` models |
| `ui/admin.py` | Django admin configuration |
| `ui/urls.py` | URL routes |
| `optimizer/main.py` | Entry point for optimization calls |
| `optimizer/model.py` | Pyomo model creation and constraints |
| `requirements.txt` | Python dependencies |
| `ui/data/data.json` | Core Satisfactory item and recipe data |

## Running Locally

1. Install dependencies:
```bash
pip install -r requirements.txt
```
2. Apply migrations:
```bash
python manage.py migrate
```
3. (Optional) Create a superuser:
```bash
python manage.py createsuperuser
```
4. Run the development server:
```bash
python manage.py runsslserver 127.0.0.1:8100
```
5. Open your browser at:
```
https://127.0.0.1:8100/
```
For advanced HTTPS setup options (mkcert, self-signed, ASGI) see [docs/dev-local.md](docs/dev-local.md).

## Optimization Details

The optimizer uses Pyomo and the HiGHS solver to minimize a weighted cost function consisting of:

- Power Use
- Item Use
- Building Use
- Resource Use
- Buildings Scaled
- Resources Scaled
- Nuclear Waste penalty

Users can adjust these weights in the web interface to favor resource efficiency, minimal machine count, or other strategies.

If a resource limit is smaller than `0.0001`, it is automatically floored to `0.0001` to avoid numerical instability.

## Authentication & Presets

- Anonymous users can still run optimizations using the default configuration.
- Authenticated users can:
- Save named settings
- Load saved configurations
- Delete unwanted presets
- Login, logout, and signup views follow Django’s standard auth flow.

## License & Credits

Created by [/u/wrigh516](https://www.reddit.com/user/wrigh516/) for Satisfactory enthusiasts.

Not affiliated with Coffee Stain Studios or the official game.

Source: <https://github.com/Scott1903/satisfactory-solver>
Website: <https://satisfactory-solver.com>

## Support

For troubleshooting or contributions:

- Open an issue or pull request on GitHub.
- Ensure that `data.json` and solver dependencies are up to date.
257 changes: 257 additions & 0 deletions docs/dev-local.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# Local HTTPS Development for `satisfactory-solver`

This guide documents several ways to run the Django application over HTTPS on macOS, Linux, or Windows. It covers trusted certificates with `mkcert`, self-signed fallbacks, and ASGI alternatives, plus the supporting dependencies and configuration required.

## Environment Assumptions

- macOS with Homebrew installed (see [brew.sh](https://brew.sh)).
- Python virtual environment already created and activated (e.g. `.venv`).
- Project root: `satisfactory-solver` with Django settings module `satopt.settings`.
- Example HTTPS endpoint: <https://127.0.0.1:8100/>.
- Windows developers should have Chocolatey installed (see [chocolatey.org/install](https://chocolatey.org/install)).

## Python Dependencies

Create (if needed) and activate a local virtual environment before installing dependencies:

- **macOS / Linux**
```bash
python3 -m venv .venv
source .venv/bin/activate
```
- **Windows (PowerShell)**
```powershell
py -3 -m venv .venv
.\.venv\Scripts\Activate.ps1
```

With the virtualenv active, install the project requirements (they already include the HTTPS helpers):

```bash
pip install -r requirements.txt
```

Key packages involved:

- `django-extensions` – exposes `runserver_plus` for HTTPS-ready dev runs.
- `pyOpenSSL` and `Werkzeug` – TLS support for `runserver_plus`.
- `uvicorn` – optional ASGI server with `--ssl-*` flags.
- `django-sslserver` – legacy fallback that can auto-generate certs.

## Prepare the Database

Before launching any HTTPS-enabled dev server, make sure the Django database is ready:

```bash
python manage.py migrate
```

Optionally seed an admin account for UI access:

```bash
python manage.py createsuperuser
```

The same one-line commands work in PowerShell. Run them once per environment (or whenever migrations change) before starting the server.

## Option A – Trusted Certificates via `mkcert` (Recommended)

`mkcert` creates locally trusted certificates so browsers do not warn about HTTPS.

1. **Install and trust the local CA**
- **macOS (Homebrew)** (see [brew.sh](https://brew.sh))
```bash
brew install mkcert
brew install nss # optional: Firefox trust store
```
- **Ubuntu / Debian**
```bash
sudo apt update
sudo apt install mkcert libnss3-tools
```
- **Fedora / RHEL**
```bash
sudo dnf install mkcert nss-tools
```
- **Arch / Manjaro**
```bash
sudo pacman -S mkcert nss
```
- **Windows (Chocolatey)** (see [chocolatey.org/install](https://chocolatey.org/install))
```powershell
choco install mkcert
choco install nss -y # optional for Firefox trust store
```

After installing the binaries, run:
```bash
mkcert -install # adds the mkcert CA to the OS trust store (and Firefox if NSS is present)
```
- View CA location: `mkcert -CAROOT`
- Remove later: `mkcert -uninstall` (then delete the CA directory).

2. **Generate project certificates**
- **macOS / Linux**
```bash
mkdir -p certs
mkcert -key-file certs/localhost-key.pem -cert-file certs/localhost.pem \
localhost 127.0.0.1 ::1
```
- **Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path certs | Out-Null
mkcert -key-file certs/localhost-key.pem -cert-file certs/localhost.pem `
localhost 127.0.0.1 ::1
```
Certificates live under `certs/` and are ignored by Git via `.gitignore`.

3. **Run the app over HTTPS**
- **Django (WSGI) with `runserver_plus`**
Command is identical in Bash and PowerShell—run it on one line:
```bash
python manage.py runserver_plus --cert-file certs/localhost.pem --key-file certs/localhost-key.pem 127.0.0.1:8100
```
- **ASGI with `uvicorn`**
- macOS / Linux
```bash
DJANGO_ALLOW_ASYNC_UNSAFE=true \
uvicorn satopt.asgi:application --host 127.0.0.1 --port 8100 \
--ssl-certfile certs/localhost.pem \
--ssl-keyfile certs/localhost-key.pem
```
- Windows (PowerShell)
```powershell
$env:DJANGO_ALLOW_ASYNC_UNSAFE = "true"
uvicorn satopt.asgi:application --host 127.0.0.1 --port 8100 `
--ssl-certfile certs/localhost.pem `
--ssl-keyfile certs/localhost-key.pem
```
> The environment variable suppresses startup `SynchronousOnlyOperation` errors that can arise from sync DB access in dev.

## Option B – Self-Signed Certificates with OpenSSL

Use this when `mkcert` is unavailable. Browsers will warn until you manually trust the cert.

1. **Generate SAN-aware self-signed certs**
- **macOS / Linux**
```bash
mkdir -p certs
cat > certs/localhost-openssl.cnf <<'CNF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
CN = localhost

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
IP.2 = ::1
CNF

openssl req -x509 -newkey rsa:2048 -nodes -days 825 \
-keyout certs/localhost-key.pem -out certs/localhost.pem \
-config certs/localhost-openssl.cnf
```
- **Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path certs | Out-Null
@'
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
CN = localhost

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
IP.2 = ::1
'@ | Set-Content -Path certs/localhost-openssl.cnf -Encoding ASCII

openssl req -x509 -newkey rsa:2048 -nodes -days 825 `
-keyout certs/localhost-key.pem -out certs/localhost.pem `
-config certs/localhost-openssl.cnf
```
> Install OpenSSL via Chocolatey (`choco install openssl`) if it is not already available.

2. **Run with the self-signed certs**
- **`runserver_plus`** (same command in Bash and PowerShell)
```bash
python manage.py runserver_plus --cert-file certs/localhost.pem --key-file certs/localhost-key.pem 127.0.0.1:8100
```
- **`uvicorn`**
- macOS / Linux
```bash
DJANGO_ALLOW_ASYNC_UNSAFE=true \
uvicorn satopt.asgi:application --host 127.0.0.1 --port 8100 \
--ssl-certfile certs/localhost.pem \
--ssl-keyfile certs/localhost-key.pem
```
- Windows (PowerShell)
```powershell
$env:DJANGO_ALLOW_ASYNC_UNSAFE = "true"
uvicorn satopt.asgi:application --host 127.0.0.1 --port 8100 `
--ssl-certfile certs/localhost.pem `
--ssl-keyfile certs/localhost-key.pem
```

3. **(Optional) Trust the cert manually**
- **Safari / Chrome**: import `certs/localhost.pem` into Keychain Access and set to *Always Trust*.
- **Firefox**: Preferences → Privacy & Security → Certificates → View Certificates → *Authorities* → **Import**.

## Option C – `django-sslserver` Quickstart

`django-sslserver` can auto-generate certs and run without additional tools. Resulting certs are still untrusted unless you import them manually.

```bash
python manage.py runsslserver 127.0.0.1:8100
```
PowerShell uses the same syntax; run the command on a single line.

Add `--nothreading` if you hit threading-related reload issues:

```bash
python manage.py runsslserver 127.0.0.1:8100 --nothreading
```
Same command applies in PowerShell; run it on a single line as well.
Or reuse the certificates from Options A/B:

```bash
python manage.py runsslserver --certificate certs/localhost.pem --key certs/localhost-key.pem 127.0.0.1:8100
```
PowerShell users can run the same command without changes.

Optional:

```bash
python manage.py runsslserver --certificate certs/localhost.pem --key certs/localhost-key.pem 127.0.0.1:8100 --nothreading
```
Again, the PowerShell command is identical when entered on one line.

## Troubleshooting

- **“Bad request version” or TLS gibberish** – ensure you open `https://` on the HTTPS port; plain HTTP against the TLS socket triggers this error.
- **`SynchronousOnlyOperation` under ASGI** – set `DJANGO_ALLOW_ASYNC_UNSAFE=true` (dev only) or prefer `runserver_plus`.
- **Firefox distrusts cert** – install `nss`, re-run `mkcert -install`, or import the certificate manually as an authority.

## Summary Checklist

1. Install helper packages in the virtualenv (`django-extensions`, `pyOpenSSL`, `Werkzeug`, `uvicorn`, `django-sslserver`).
2. (Already configured) Ensure `'sslserver'` and `'django_extensions'` stay in `INSTALLED_APPS`.
3. Generate certificates via `mkcert` (trusted) or OpenSSL (self-signed).
4. Launch the server with `runserver_plus`, `uvicorn`, or `runsslserver` using the generated certs.
File renamed without changes.
Binary file modified requirements.txt
Binary file not shown.
2 changes: 2 additions & 0 deletions satopt/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
# --- Application definition ---
INSTALLED_APPS = [
'ui',
'sslserver',
'django_extensions',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand Down
Loading