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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ logs/*
### Python related
# Virtual environments
venv/
.venv/

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
push:
branches: [master]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
ci:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Sync dependencies
run: uv sync --frozen

- name: Lint
run: uv run ruff check .

- name: Format check
run: uv run ruff format --check .

- name: Test
run: uv run pytest -q
29 changes: 0 additions & 29 deletions .github/workflows/pythonapp.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ characters/
### Python related
# Virtual environments
venv/
.venv/

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
14 changes: 0 additions & 14 deletions .travis.yml

This file was deleted.

14 changes: 10 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
FROM python:3.11-alpine

RUN apk --no-cache add git
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /app

COPY requirements.txt start_server.py ./
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ENV UV_LINK_MODE=copy \
UV_COMPILE_BYTECODE=1 \
UV_PROJECT_ENVIRONMENT=/app/.venv \
PATH="/app/.venv/bin:$PATH"

COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project

COPY start_server.py ./
COPY server/ server/
COPY migrations/ migrations/
COPY storage/ storage/

CMD python ./start_server.py
CMD ["python", "./start_server.py"]
47 changes: 18 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ KFO-Server is the official Python-based server for Attorney Online, forked from

In order to set up the server, you must follow these instructions. This assumes you are familiar with using a terminal.

### Install Python
### Install uv

* Install the [latest version of Python](https://www.python.org/downloads/). You will need Python 3.11 or newer.
* If you run Windows, make sure to check the "Add Python to PATH" and install pip checkboxes in the installer
* If you run anything other than Windows, you should read "Advanced setup instructions" below.
KFO-Server uses [uv](https://docs.astral.sh/uv/) to manage the Python toolchain and dependencies.
It picks up the required Python version (3.11+) from `pyproject.toml` automatically — you do not need to install Python separately.

Install uv by following the [official instructions](https://docs.astral.sh/uv/getting-started/installation/). The short version:

* On Linux / macOS: `curl -LsSf https://astral.sh/uv/install.sh | sh`
* On Windows (PowerShell): `powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"`

### Download server software

Expand All @@ -22,42 +26,27 @@ If you don't want to use Git, you can download the latest zip of KFO-Server [her

### Install dependencies

In order to install dependencies, you will need to open a terminal.

On Windows, you can do this by pressing Win+R, typing in `cmd`, and pressing Enter.
On Linux, you can do this by pressing Ctrl+Alt+T.

You should then navigate to the folder where the server is located.

Take note that depending on your operating system, the command for python may be python3 or python.
You should also verify the version by running `python --version` or `python3 --version`.

First, we need to create the virtual environment. This can be done by running the following command:
From the project folder, run:

```bash
python -m venv venv
uv sync
```

Then, we need to activate the virtual environment.
If you're on a unix system (bash or similar), you can run the following command:
This creates a virtual environment under `.venv/` and installs every dependency pinned in `uv.lock`. Re-run `uv sync` any time you pull new changes to stay in sync with the lockfile.

```bash
./venv/bin/pip install -r requirements.txt
```
Format the codebase with:

If you're on Windows (cmd), you may have to do this instead:

```batch
venv\Scripts\pip install -r requirements.txt
```bash
uv run ruff format .
```

### Configure tsuserver
### Configure the server

* Copy `config_sample` to `config`
* Edit the values in the `.yaml` files to your liking.
* Be sure to check your YAML file for syntax errors. Use this website: <http://www.yamllint.com/>
* *Use spaces only; do not use tabs.*
* You don't need to copy characters into the `characters` folder *unless* you specifically chose to disable iniswapping in an area (in `areas.yaml`). In this case, all tsuserver needs to know is the `char.ini` of each character. It doesn't need sprites.
* You don't need to copy characters into the `characters` folder *unless* you specifically chose to disable iniswapping in an area (in `areas.yaml`). In this case, all the server needs to know is the `char.ini` of each character. It doesn't need sprites.

### Run

Expand All @@ -70,12 +59,12 @@ To stop the server, press Ctrl+C in the terminal.

You can also use docker to run KFO-server. First you need to install [Docker](https://get.docker.com/) and [Docker Compose](https://docs.docker.com/compose/install/).

Once you have everything configured, do `docker-compose up`. It will build the image and start tsuserver up for you. If you accidentally restart the server, the container will automatically start back up. If you're not understanding why it's starting, try starting it up manually:
Once you have everything configured, do `docker compose up`. It will build the image and start the server for you. If you accidentally restart the server, the container will automatically start back up. If you're not understanding why it's starting, try starting it up manually:

## Pro Tips

* To keep the server running even if your login shell is closed, use a multiplexer, such as screen or tmux.
* For more info about available command, see [Commands](https://github.com/Crystalwarrior/KFO-Server/blob/master/docs/commands.md). You may also use the /help command on the server.
* For more info about available commands, see [docs/commands.md](docs/commands.md). You may also use the `/help` command on the server.
* For more info about Python virtual environments, refer to ["Creating Virtual Environments"](https://docs.python.org/3/library/venv.html#creating-virtual-environments)
* In order to join your server, it has to be accessible to the public internet. You might need to forward the ports in config.yaml to make this work.
* If you can't portforward, you may want to check out [ngrok](https://ngrok.com/). It's a service that allows you to expose your local server to the internet. It's free, but you can also pay for a subscription to get more features.
Expand Down
2 changes: 1 addition & 1 deletion config_sample/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ secure_websocket_port: 443
asset_url:

# Whether the server should be advertised on the server list.
use_masterserver: true
use_masterserver: false
# How the server should be listed on the server list.
masterserver_name: My First Server
masterserver_description: This is my flashy new server
Expand Down
6 changes: 2 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
version: "3.3"
services:
tsuserver:
kfo-server:
build: .
image: tsuserver
image: kfo-server
ports:
- 27016:27016
- 50001:50001
Expand All @@ -11,4 +10,3 @@ services:
- ./logs:/app/logs
- ./config:/app/config
restart: unless-stopped

74 changes: 70 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,71 @@
[tool.black]
[project]
name = "kfo-server"
version = "3.3.0"
description = "KFO-Server is the official Python-based server for Attorney Online, forked from tsuserver3."
readme = "README.md"
license = { file = "LICENSE.md" }
requires-python = ">=3.11"
dependencies = [
"aiohttp==3.13.2",
"aiosignal==1.4.0",
"arrow==1.3.0",
"async-timeout==4.0.3",
"attrs==23.1.0",
"certifi==2023.7.22",
"charset-normalizer==3.3.2",
"discord.py==2.5.2",
"frozenlist==1.6.0",
"geoip2==4.7.0",
"idna==3.4",
"maxminddb==2.5.1",
"multidict==6.4.3",
"oyaml==1.0",
"pystun3==1.0.0",
"python-dateutil==2.8.2",
"PyYAML==6.0.1",
"requests==2.31.0",
"six==1.16.0",
"timeparse-plus==1.2.0",
"types-python-dateutil==2.8.19.14",
"urllib3==2.1.0",
"websockets==12.0",
"yarl==1.20.0",
]

[dependency-groups]
dev = [
"pytest",
"pytest-asyncio",
"tox>=4.21",
"tox-uv>=1",
"ruff>=0.15",
]

[tool.pytest.ini_options]
asyncio_mode = "auto"

[tool.ruff]
line-length = 120
target-version = ["py311"]
# You can add patterns here if you need to exclude generated files, etc.
# extend-exclude = []
target-version = "py311"
# scripts/ holds ad-hoc utilities that don't follow the server's style.
exclude = ["scripts"]

[tool.ruff.lint.per-file-ignores]
# E402: command modules are imported after the decorator/__all__ machinery is defined.
# F403: star imports are intentional — each submodule registers commands via its own __all__.
"server/commands/__init__.py" = ["E402", "F403"]

[tool.uv]
package = false

[tool.tox]
requires = ["tox>=4.21", "tox-uv>=1"]
env_list = ["py311"]
skip_missing_interpreters = true

[tool.tox.env_run_base]
runner = "uv-venv-lock-runner"
package = "skip"
dependency_groups = ["dev"]
set_env = { PYTHONPATH = "{toxinidir}" }
commands = [["pytest", "-q"]]
24 changes: 0 additions & 24 deletions requirements.txt

This file was deleted.

1 change: 0 additions & 1 deletion scripts/music2yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os
import sys

from shutil import copy2

os.chdir(os.path.dirname(__file__))

Expand Down
Loading
Loading