Skip to content

Commit

Permalink
beta
Browse files Browse the repository at this point in the history
  • Loading branch information
K-ETFreeman committed Dec 25, 2024
1 parent adcc746 commit 5933022
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 11 deletions.
28 changes: 21 additions & 7 deletions server/ladder_service/ladder_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from server.decorators import with_logger
from server.exceptions import DisabledError
from server.game_service import GameService
from server.player_service import PlayerService
from server.games import InitMode, LadderGame
from server.games.ladder_game import GameClosedError
from server.ladder_service.game_name import game_name
Expand All @@ -59,11 +60,13 @@ def __init__(
self,
database: FAFDatabase,
game_service: GameService,
player_service: PlayerService,
violation_service: ViolationService,
):
self._db = database
self._informed_players: set[Player] = set()
self.game_service = game_service
self.player_service = player_service
self.queues = {}
self.violation_service = violation_service

Expand All @@ -75,6 +78,7 @@ async def initialize(self) -> None:
self._update_cron = aiocron.crontab("*/10 * * * *", func=self.update_data)

async def update_data(self) -> None:
prev_pools_veto_data = self.get_pools_veto_data()
async with self._db.acquire() as conn:
map_pool_maps = await self.fetch_map_pools(conn)
db_queues = await self.fetch_matchmaker_queues(conn)
Expand Down Expand Up @@ -122,6 +126,10 @@ async def update_data(self) -> None:
if queue_name not in db_queues:
self.queues[queue_name].shutdown()
del self.queues[queue_name]
current_pools_veto_data = self.get_pools_veto_data()
if (current_pools_veto_data != prev_pools_veto_data):
for player in self.player_service.all_players:
await player.update_vetoes(current_pools_veto_data)

async def fetch_map_pools(self, conn) -> dict[int, tuple[str, list[Map]]]:
result = await conn.execute(
Expand Down Expand Up @@ -164,6 +172,7 @@ async def fetch_map_pools(self, conn) -> dict[int, tuple[str, list[Map]]]:
try:
params = json.loads(row.map_params)
map_type = params["type"]
params.map_pool_map_version_id = row.map_pool_map_version_id
if map_type == "neroxis":
map_list.append(
NeroxisGeneratedMap.of(params, row.weight)
Expand Down Expand Up @@ -538,19 +547,17 @@ def get_displayed_rating(player: Player) -> float:
pool, _, _, veto_tokens_per_player, max_tokens_per_map, minimum_maps_after_veto = queue.map_pools[pool.id]

Check warning on line 547 in server/ladder_service/ladder_service.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/ladder_service/ladder_service.py#L547

Unused variable 'veto_tokens_per_player'

vetoesMap = defaultdict(int)
tokensTotalPerPlayer = defaultdict(int)

for (id, map) in pool.maps.items():

Check warning on line 551 in server/ladder_service/ladder_service.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/ladder_service/ladder_service.py#L551

Redefining built-in 'id'

Check warning on line 551 in server/ladder_service/ladder_service.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/ladder_service/ladder_service.py#L551

Unused variable 'id'
for player in all_players:
vetoesMap[map.map_pool_map_version_id] += player.vetoes.get(map.map_pool_map_version_id, 0)
tokensTotalPerPlayer[player.id] += player.vetoes.get(map.map_pool_map_version_id, 0)

for player in all_players:
if (tokensTotalPerPlayer[player.id] > veto_tokens_per_player):
raise RuntimeError(f"Player {player.id} has too many vetoes!")

if (max_tokens_per_map == 0):
max_tokens_per_map = self.calculate_dynamic_tokens_per_map(minimum_maps_after_veto, vetoesMap.values())
if (max_tokens_per_map == 0):
self._logger.error("calculate_dynamic_tokens_per_map received impossible vetoes setup, all vetoes cancelled for a match")
vetoesMap = {}
max_tokens_per_map = 1

game_map = pool.choose_map(played_map_ids, vetoesMap, max_tokens_per_map)

Expand Down Expand Up @@ -720,8 +727,15 @@ def calculate_dynamic_tokens_per_map(self, M: float, tokens: list[int]) -> float
if (result <= upperLimit):
return result

Check warning on line 729 in server/ladder_service/ladder_service.py

View workflow job for this annotation

GitHub Actions / flake8

blank line contains whitespace
raise Exception("Failed to calculate dynamic tokens per map: impossible vetoes setup")
return 0

Check warning on line 731 in server/ladder_service/ladder_service.py

View workflow job for this annotation

GitHub Actions / flake8

blank line contains whitespace
def get_pools_veto_data(self) -> list[tuple[list[int], int, int]]:
result = []
for queue in self.queues.values():
for map_pool, min_rating, max_rating, veto_tokens_per_player, max_tokens_per_map, minimum_maps_after_veto in queue.map_pools.values():

Check failure on line 735 in server/ladder_service/ladder_service.py

View workflow job for this annotation

GitHub Actions / flake8

import 'map_pool' from line 20 shadowed by loop variable

Check warning on line 735 in server/ladder_service/ladder_service.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/ladder_service/ladder_service.py#L735

Unused variable 'min_rating'

Check notice on line 735 in server/ladder_service/ladder_service.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/ladder_service/ladder_service.py#L735

import 'map_pool' from line 20 shadowed by loop variable (F402)
result.append(([map.map_pool_map_version_id for map in map_pool.maps.values()], veto_tokens_per_player, max_tokens_per_map))
return result

async def get_game_history(
self,
players: list[Player],
Expand Down
2 changes: 1 addition & 1 deletion server/lobbyconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ async def command_set_party_factions(self, message):

async def command_set_player_vetoes(self, message):
converted = {v['map_pool_map_version_id']: v['veto_tokens_applied'] for v in message["vetoes"]}

Check failure on line 1319 in server/lobbyconnection.py

View workflow job for this annotation

GitHub Actions / flake8

multiple spaces after operator

Check warning on line 1319 in server/lobbyconnection.py

View workflow job for this annotation

GitHub Actions / flake8

Single quotes found but double quotes preferred
self.player.vetoes = converted
await self.player.update_vetoes(self.ladder_service.get_pools_veto_data(), converted)

async def send_warning(self, message: str, fatal: bool = False):
"""
Expand Down
2 changes: 1 addition & 1 deletion server/matchmaker/map_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def choose_map(self, played_map_ids: Iterable[int] = (), vetoesMap = None, max_t
least_common_ids = {id_ for id_, _ in least_common}

Check failure on line 57 in server/matchmaker/map_pool.py

View workflow job for this annotation

GitHub Actions / flake8

too many blank lines (3)

Check notice on line 57 in server/matchmaker/map_pool.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/matchmaker/map_pool.py#L57

Trailing whitespace

#multiply weight by 2 if map is least common and not vetoed by anyone

Check failure on line 59 in server/matchmaker/map_pool.py

View workflow job for this annotation

GitHub Actions / flake8

block comment should start with '# '
mapList = list((map.map_pool_map_version_id, map, 2 if (map.id in least_common_ids) and (vetoesMap.get(map.map_pool_map_version_id) == 0) else 1) for id, map in self.maps.items())
mapList = list((map.map_pool_map_version_id, map, 2 if (map.id in least_common_ids) and (vetoesMap.get(map.map_pool_map_version_id,0) == 0) else 1) for id, map in self.maps.items())

weights = [max(0, (1 - vetoesMap.get(id, 0) / max_tokens_per_map) * map.weight * least_common_multiplier) for id, map, least_common_multiplier in mapList]
map = random.choices(mapList, weights=weights, k=1)[0][1]

Check warning on line 63 in server/matchmaker/map_pool.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/matchmaker/map_pool.py#L63

Redefining built-in 'map'

Check warning on line 63 in server/matchmaker/map_pool.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/matchmaker/map_pool.py#L63

Standard pseudo-random generators are not suitable for security/cryptographic purposes.
Expand Down
30 changes: 28 additions & 2 deletions server/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,36 @@ def vetoes(self) -> dict[int, int]:
def vetoes(self, value: dict[int, int]) -> None:
if not isinstance(value, dict):
raise ValueError("Vetoes must be a dictionary")
if not all(isinstance(key, int) and isinstance(val, int) for key, val in value.items()):
raise ValueError("Vetoes dictionary must contain only integer keys and values")
if not all(isinstance(key, int) and isinstance(val, int) and val >= 0 for key, val in value.items()):
raise ValueError("Incorrect vetoes dictonary")
self._vetoes = value

Check notice on line 103 in server/players.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/players.py#L103

Trailing whitespace

async def update_vetoes(self, pools_vetodata: list[tuple[list[int], int, int]], current: dict = None) -> None:
if current is None:
current = self.vetoes
fixedVetoes = {}
vetoDatas = []

Check notice on line 109 in server/players.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/players.py#L109

Trailing whitespace
for (map_pool_map_version_ids, veto_tokens_per_player, max_tokens_per_map) in pools_vetodata:
sum = 0

Check warning on line 111 in server/players.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/players.py#L111

Redefining built-in 'sum'
for id in map_pool_map_version_ids:

Check warning on line 112 in server/players.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

server/players.py#L112

Redefining built-in 'id'
new_tokens_applied = max(current.get(id, 0),0)
if (sum + new_tokens_applied > veto_tokens_per_player or (max_tokens_per_map > 0 and new_tokens_applied > max_tokens_per_map)):
new_tokens_applied = min(veto_tokens_per_player - sum, max_tokens_per_map)
if (new_tokens_applied == 0):
continue
vetoDatas.append({"map_pool_map_version_id": id, "veto_tokens_applied": new_tokens_applied})
fixedVetoes[id] = new_tokens_applied
sum += new_tokens_applied
if fixedVetoes == self.vetoes == current:
return
self.vetoes = fixedVetoes
if self.lobby_connection is None:
return
await self.lobby_connection.send({
"command": "vetoes_changed",
"vetoesData": vetoDatas
})

def power(self) -> int:
"""An artifact of the old permission system. The client still uses this
number to determine if a player gets a special category in the user list
Expand Down
2 changes: 2 additions & 0 deletions server/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,10 @@ def of(cls, params: dict, weight: int = 1):
raise Exception("spawns is not a multiple of 2")

version = params["version"]
map_pool_map_version_id = params["map_pool_map_version_id"]
return cls(
cls._get_id(version, spawns, map_size_pixels),
map_pool_map_version_id,
version,
spawns,
map_size_pixels,
Expand Down

0 comments on commit 5933022

Please sign in to comment.