Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporf for multiple games #13

Merged
merged 8 commits into from
Nov 12, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Tests
on:
push:
branches:
- main
- '**'

jobs:
check:
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Publish Python Package to PyPI
on:
release:
types: [published]
jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install build twine
- name: Build package
run: |
python -m build
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
12 changes: 0 additions & 12 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Linux / Mac Script",
"type": "python",
"request": "launch",
"program": "maps4fs/ui.py",
"console": "integratedTerminal",
"justMyCode": true,
"env": {
"PYTHONPATH": "${workspaceFolder}:${PYTHONPATH}",
"LOG_LEVEL": "DEBUG",
}
},
{
"name": "Streamlit: webui",
"type": "process",
Expand Down
47 changes: 39 additions & 8 deletions bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
logger = mfs.Logger(__name__, level="DEBUG")

# region constants
GAME_CODES = {
"FS22": "Farming Simulator 22",
"FS25": "Farming Simulator 25",
}
MAP_SIZES = ["2048", "4096", "8192", "16384"]
MAX_HEIGHTS = {
"100": "🍀 For flatlands",
Expand All @@ -29,7 +33,6 @@

# region directories
working_directory = os.getcwd()
map_template = os.path.join(working_directory, "data", "map-template.zip")
maps_directory = os.path.join(working_directory, "maps")
archives_directory = os.path.join(working_directory, "archives")
stats_directory = os.path.join(working_directory, "stats")
Expand Down Expand Up @@ -77,12 +80,13 @@ class Session:
dem_settings (generate.DemSettings): DEM settings.
"""

def __init__(self, telegram_id: int, coordinates: tuple[float, float]):
def __init__(self, telegram_id: int, game_code: str):
self.telegram_id = telegram_id
self.timestamp = int(datetime.now().timestamp())
self.name = f"{self.telegram_id}_{self.timestamp}"
self.map_directory = os.path.join(maps_directory, self.name)
self.coordinates = coordinates
self.game = mfs.Game.from_code(game_code)
self.coordinates = None
self.distance = None
self.max_height = None

Expand All @@ -93,17 +97,17 @@ def run(self) -> tuple[str, str]:
tuple[str, str]: Paths to the preview and the archive.
"""
mp = mfs.Map(
self.game,
self.coordinates,
self.distance,
self.map_directory,
blur_seed=5,
max_height=self.max_height,
map_template=map_template,
logger=logger,
)
mp.generate()
# preview_path = mp.previews()[0]
preview_path = None # Disabled to avoid Docker 137 error (OUT OF MEMORY).
preview_path = None # Disabled to avoid Docker 137 error (OUT OF MEMORY).
archive_path = mp.pack(os.path.join(archives_directory, self.name))
return preview_path, archive_path

Expand Down Expand Up @@ -198,13 +202,38 @@ async def button_coffee(message: types.Message) -> None:

@dp.message_handler(Text(equals=Buttons.GENERATE.value))
async def button_generate(message: types.Message) -> None:
"""Handles the Generate button, registers the coordinates handler.
"""Handles the Generate button, creates inline buttons for the game selection.

Args:
message (types.Message): Message, which triggered the handler.
"""
await log_event(message)

buttons = {}
for game_code, game_name in GAME_CODES.items():
buttons[f"game_code_{game_code}"] = game_name

await bot.send_message(
message.from_user.id,
Messages.CHOOSE_GAME.value,
reply_markup=await keyboard(buttons),
)


@dp.callback_query_handler(text_contains="game_code_")
async def game_choose(message: types.Message) -> None:
"""Handles the catch of the game selection, registers the coordinates handler.

Args:
message (types.Message): Message, which triggered the handler.
"""
await log_event(message)

game_code = message.data.rsplit("_", 1)[-1]

session = Session(message.from_user.id, game_code)
sessions[message.from_user.id] = session

dp.register_message_handler(coordinates)

await bot.send_message(
Expand Down Expand Up @@ -263,8 +292,10 @@ async def coordinates(message: types.Message) -> None:
)
return

telegram_id = message.from_user.id
sessions[telegram_id] = Session(telegram_id, (latitude, longitude))
session = sessions.get(message.from_user.id)
if not session:
return
session.coordinates = (latitude, longitude)

sizes = MAP_SIZES
indicators = ["🟢", "🟢", "🟡", "🔴"]
Expand Down
2 changes: 2 additions & 0 deletions bot/bot_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class Messages(Enum):

CANCELLED = "The operation has been cancelled."

CHOOSE_GAME = "Choose the game for which you want to generate a map."

ENTER_COORDINATES = (
"Enter the coordinates of the center of the map\."
"The coordinates are latitude and longitude separated by a comma\.\n\n"
Expand Down
File renamed without changes.
96 changes: 96 additions & 0 deletions data/fs22-texture-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
[
{
"name": "animalMud",
"count": 4
},
{
"name": "asphalt",
"count": 4,
"tags": { "highway": ["motorway", "trunk", "primary"] },
"width": 8,
"color": [70, 70, 70]
},
{
"name": "cobbleStone",
"count": 4
},
{
"name": "concrete",
"count": 4,
"tags": { "building": "true" },
"width": 8,
"color": [130, 130, 130]
},
{
"name": "concreteRubble",
"count": 4
},
{
"name": "concreteTiles",
"count": 4
},
{
"name": "dirt",
"count": 4
},
{
"name": "dirtDark",
"count": 2,
"tags": { "highway": ["unclassified", "residential", "track"] },
"width": 2,
"color": [33, 67, 101]
},
{
"name": "forestGround",
"count": 4,
"tags": { "landuse": "farmland" },
"color": [47, 107, 85]
},
{
"name": "forestGroundLeaves",
"count": 4
},
{
"name": "grass",
"count": 4,
"tags": { "natural": "grassland" },
"color": [34, 255, 34]
},
{
"name": "grassDirt",
"count": 4,
"tags": { "natural": ["wood", "tree_row"] },
"width": 2,
"color": [0, 252, 124]
},
{
"name": "gravel",
"count": 4,
"tags": { "highway": ["secondary", "tertiary", "road"] },
"width": 4,
"color": [140, 180, 210]
},
{
"name": "groundBricks",
"count": 4
},
{
"name": "mountainRock",
"count": 4
},
{
"name": "mountainRockDark",
"count": 4
},
{
"name": "riverMud",
"count": 4
},
{
"name": "waterPuddle",
"count": 0,
"tags": { "natural": "water", "waterway": "true" },
"width": 10,
"color": [255, 20, 20]
}
]
2 changes: 1 addition & 1 deletion dev/clean_trash.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh

# Directories to be removed
dirs=".mypy_cache .pytest_cache htmlcov dist"
dirs=".mypy_cache .pytest_cache htmlcov dist archives cache logs maps temp"

# Files to be removed
files=".coverage"
Expand Down
2 changes: 1 addition & 1 deletion dev/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
opencv-python
osmnx
osmnx<2.0.0
rasterio
python_dotenv
aiogram==2.25.1
Expand Down
2 changes: 1 addition & 1 deletion docker/requirements_bot.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
opencv-python
osmnx
osmnx<2.0.0
rasterio
python_dotenv
aiogram==2.25.1
Expand Down
2 changes: 1 addition & 1 deletion docker/requirements_webui.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
opencv-python
osmnx
osmnx<2.0.0
rasterio
streamlit
tqdm
1 change: 1 addition & 0 deletions maps4fs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=missing-module-docstring
from maps4fs.generator.game import Game
from maps4fs.generator.map import Map
from maps4fs.logger import Logger
22 changes: 20 additions & 2 deletions maps4fs/generator/component.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""This module contains the base class for all map generation components."""

from typing import Any
from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
from maps4fs.generator.game import Game


# pylint: disable=R0801, R0903
Expand All @@ -17,16 +22,29 @@ class Component:

def __init__(
self,
game: Game,
coordinates: tuple[float, float],
distance: int,
map_directory: str,
logger: Any = None,
**kwargs, # pylint: disable=W0613
**kwargs, # pylint: disable=W0613, R0913, R0917
):
self.game = game
self.coordinates = coordinates
self.distance = distance
self.map_directory = map_directory
self.logger = logger
self.kwargs = kwargs

self.preprocess()

def preprocess(self) -> None:
"""Prepares the component for processing. Must be implemented in the child class.

Raises:
NotImplementedError: If the method is not implemented in the child class.
"""
raise NotImplementedError

def process(self) -> None:
"""Launches the component processing. Must be implemented in the child class.
Expand Down
16 changes: 5 additions & 11 deletions maps4fs/generator/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""This module contains the Config class for map settings and configuration."""

from __future__ import annotations

import os
from typing import Any
from xml.etree import ElementTree as ET

from maps4fs.generator.component import Component
Expand All @@ -19,16 +20,9 @@ class Config(Component):
info, warning. If not provided, default logging will be used.
"""

def __init__(
self,
coordinates: tuple[float, float],
distance: int,
map_directory: str,
logger: Any = None,
**kwargs,
):
super().__init__(coordinates, distance, map_directory, logger)
self._map_xml_path = os.path.join(self.map_directory, "maps", "map", "map.xml")
def preprocess(self) -> None:
self._map_xml_path = self.game.map_xml_path(self.map_directory)
self.logger.debug(f"Map XML path: {self._map_xml_path}")

def process(self):
self._set_map_size()
Expand Down
Loading
Loading