From 172a9185077c33098ae239b72c9d56467f7e73f7 Mon Sep 17 00:00:00 2001 From: TatLead Date: Wed, 13 Mar 2024 09:14:00 +0000 Subject: [PATCH] Update Dockerfile --- Dockerfile | 3 ++ README.md | 101 ++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 2 +- main.py | 14 ++++-- protocols/BeamMP.py | 2 + protocols/Factorio.py | 2 + protocols/MasterServer.py | 9 +++- protocols/Palworld.py | 2 + protocols/Scum.py | 2 + 9 files changed, 129 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 567f61a..6064dfe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,8 @@ FROM python:3.12 +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + WORKDIR /app COPY requirements.txt ./ diff --git a/README.md b/README.md index f1a7343..17a8af1 100644 --- a/README.md +++ b/README.md @@ -29,3 +29,104 @@ This project is licensed under the MIT License. ## Stargazers over time [![Stargazers over time](https://starchart.cc/opengsq/opengsq-master-server.svg?variant=adaptive)](https://starchart.cc/opengsq/opengsq-master-server) + +--- + +# OpenGSQ Master Server + +This project provides a self-hosted master server solution for your game servers. + +## Development Setup + +Follow these steps to set up your development environment: + +1. Create a virtual environment: + ```bash + python -m venv venv + ``` +2. Activate the virtual environment: + - On Windows, run: `venv\Scripts\activate` + - On Unix or MacOS, run: `source venv/bin/activate` +3. Install the required packages: + ```bash + pip install -r requirements.txt + ``` + +## Configuration + +Copy the `.env.example` file to a new file named `.env` and update the variables as needed: + +```bash +cp .env.example .env +``` + +Here's what each variable in the `.env` file represents: + +- `DATABASE_URL`: The URL of your mongodb database. +- `PORT`: The port number on which the Flask application will run. +- `FACTORIO_USERNAME`: Your Factorio username. +- `FACTORIO_TOKEN`: Your Factorio token. +- `USERNAME`: The username for the Flask-MonitoringDashboard. +- `PASSWORD`: The password for the Flask-MonitoringDashboard. +- `SECURITY_TOKEN`: The security token for the Flask-MonitoringDashboard. + +## Running the Application + +You can start the scheduled task or run the Flask application in debug mode: + +- Start the scheduled task: + ```bash + python main.py + ``` +- Run Flask in debug mode: + ```bash + python app.py + ``` +- Run Protocol: + ```bash + python -m protocol.BeamMP + ``` + +## Self-Hosting + +You can use Docker Compose to self-host the application. Here's how: + +1. Ensure that you have the following file structure: + - `docker-compose.yml` + - `.env` + +2. Create a `docker-compose.yml` file with the following content: + + ```yml + version: '3.8' + services: + flask: + image: opengsq/opengsq-master-server:latest + command: gunicorn -w 4 -b :8000 app:app + container_name: opengsq-master-server-flask + environment: + - FLASK_ENV=production + env_file: + - .env + ports: + - ${PORT}:8000 + restart: always + volumes: + - ./data:/app/data + + schedule: + image: opengsq/opengsq-master-server:latest + command: python -u main.py + container_name: opengsq-master-server-schedule + env_file: + - .env + restart: always + ``` + +3. Create a `.env` file as stated in the Configuration section. + +4. Run the following command to start the application: + + ```bash + docker-compose up -d + ``` diff --git a/docker-compose.yml b/docker-compose.yml index 8f18e08..a5048b2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,7 @@ services: schedule: build: . - command: python -u main.py + command: python main.py container_name: opengsq-master-server-schedule env_file: - .env diff --git a/main.py b/main.py index a6e3ef7..6324d5f 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ import time import schedule -from protocols import MasterServer, BeamMP, Factorio, Palworld, Scum +from protocols import MasterServer threads: dict[str, Thread] = {} @@ -13,10 +13,14 @@ def run_threaded(master_server: MasterServer): threads[master_server.key].start() -schedule.every(5).minutes.do(run_threaded, BeamMP()).run() -schedule.every(5).minutes.do(run_threaded, Factorio()).run() -schedule.every(5).minutes.do(run_threaded, Palworld()).run() -schedule.every(5).minutes.do(run_threaded, Scum()).run() +for Protocol in MasterServer.__subclasses__(): + protocol = Protocol() + + # Creates an index on protocol collection. + protocol.create_index() + + # Create a schedule task + schedule.every(5).minutes.do(run_threaded, protocol).run() for job in schedule.get_jobs(): print(f"Job: {job}, Next run: {job.next_run}, Period: {job.period}") diff --git a/protocols/BeamMP.py b/protocols/BeamMP.py index 54e9333..23670cc 100644 --- a/protocols/BeamMP.py +++ b/protocols/BeamMP.py @@ -7,6 +7,8 @@ class BeamMP(MasterServer): def __init__(self) -> None: super().__init__('BeamMP') + + def create_index(self): self.collection.create_index({'ip': 1, 'port': 1}) def job(self): diff --git a/protocols/Factorio.py b/protocols/Factorio.py index f8cdc60..22c7ab7 100644 --- a/protocols/Factorio.py +++ b/protocols/Factorio.py @@ -8,6 +8,8 @@ class Factorio(MasterServer): def __init__(self) -> None: super().__init__('Factorio') + + def create_index(self): self.collection.create_index('server_id') self.collection.create_index('host_address') diff --git a/protocols/MasterServer.py b/protocols/MasterServer.py index 3e092cb..4f8b94c 100644 --- a/protocols/MasterServer.py +++ b/protocols/MasterServer.py @@ -11,6 +11,9 @@ load_dotenv() +uri = os.getenv('DATABASE_URL') +client = MongoClient(uri) + class MasterServer(ABC): def __init__(self, key: str) -> None: @@ -20,8 +23,6 @@ def __init__(self, key: str) -> None: @staticmethod def get_db(): - uri = os.getenv('DATABASE_URL') - client = MongoClient(uri) db = client['MasterServer'] return db @@ -29,6 +30,10 @@ def get_db(): def key(self): return self._key + @abstractmethod + def create_index(self): + pass + @abstractmethod def job(self): pass diff --git a/protocols/Palworld.py b/protocols/Palworld.py index b4a71f9..efbabdf 100644 --- a/protocols/Palworld.py +++ b/protocols/Palworld.py @@ -9,6 +9,8 @@ class Palworld(MasterServer): def __init__(self) -> None: super().__init__('Palworld') + + def create_index(self): self.collection.create_index('server_id') self.collection.create_index({'address': 1, 'port': 1}) diff --git a/protocols/Scum.py b/protocols/Scum.py index fa1d247..1497ccc 100644 --- a/protocols/Scum.py +++ b/protocols/Scum.py @@ -13,6 +13,8 @@ class Scum(MasterServer): def __init__(self) -> None: super().__init__('Scum') + + def create_index(self): self.collection.create_index({'ip': 1, 'port': 1}) def job(self):