Skip to content
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
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Dofutils
Collection of useful things to build Dofus Retro bot/emulator. \
Written in Python3. Require Python >= 3.8. and [Poetry](https://python-poetry.org/).
Written in Python3. Require Python >= 3.11.

## Installation
use `poetry install dofutils`
add dofutils in your project by using `uv add dofutils`.

## Developpement
clone the repos using `git clone` then
use `poetry install` to install the dev dependencies. \
use `poetry run task test` to launch all tests. \
use `poetry run task lint` to format the project. \
use `poetry run task check` to type check the project. \
use `poetry run task clean` to clean import and var.
use `mise install && mise run install` to install the dev dependencies. \
use `uv run task test` to launch all tests. \
use `uv run task lint` to format the project. \
use `uv run task check` to type check the project. \
use `uv run task clean` to clean import and var.

## Acknowledgement
[Vincent Quatrevieux](https://github.com/vincent4vx) : the author of the original lib \
Expand Down
15 changes: 11 additions & 4 deletions dofutils/maps/serializer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import Self

from dofutils.encoding import Base64, CheckSum, Key
from dofutils.maps.constant import CellMovement
Expand Down Expand Up @@ -29,7 +30,7 @@ class InteractiveObjectData(CellLayerData):
rotation: int = 0


@dataclass(frozen=True)
@dataclass(frozen=True, slots=True)
class CellData:
line_of_sight: bool
movement: CellMovement
Expand All @@ -42,18 +43,21 @@ class CellData:
class DefaultMapDataSerializer:
cell_data_length = 10

def __init__(self):
def __init__(self) -> None:
self._cache: dict[str, CellData] | None = None

def enable_cache(self) -> None:
def enable_cache(self) -> Self:
self._cache = {}
return self

def disable_cache(self) -> None:
def disable_cache(self) -> Self:
self._cache = None
return self

def deserialize(self, map_data: str) -> list[CellData]:
if len(map_data) % self.cell_data_length:
raise ValueError("Invalid map data")

return [self._deserialize_cell(map_data[i : i + 10]) for i in range(0, len(map_data), 10)]

def serialize(self, cells: list[CellData]) -> str:
Expand All @@ -65,6 +69,7 @@ def with_key(self, key: Key | str) -> EncryptedMapDataSerializer:
def _deserialize_cell(self, value: str) -> CellData:
if self._cache is not None and value in self._cache:
return self._cache[value]

d = Base64.to_bytes(value)
cell = CellData(
bool(d[0] & 1),
Expand All @@ -84,8 +89,10 @@ def _deserialize_cell(self, value: str) -> CellData:
((d[0] & 2) << 12) + ((d[7] & 1) << 12) + (d[8] << 6) + d[9], 0, bool(d[7] & 4), bool(d[7] & 2)
),
)

if self._cache is not None:
self._cache[value] = cell

return cell

@staticmethod
Expand Down