Skip to content

Introduce ext.dota2 - Dota 2 Game Coordinator extension #460

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

Draft
wants to merge 68 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
de7a99f
🪧Compile protobufs into `.py` mirrors
Aluerie Jan 23, 2024
e21b9ef
🐸Initial implementation for Dota2 GC
Aluerie Jan 23, 2024
513ea0c
📃Initial docs for ext.dota2
Aluerie Jan 23, 2024
60e4c39
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2024
89bdc97
✒️Stealth edit to `fetch_top_source_tv_games` docstring
Aluerie Jan 23, 2024
dd0a3b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2024
6355e21
Apply suggestions from code review by Gobot
Aluerie Jan 23, 2024
89b5b01
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2024
ca12e0e
Apply suggestions from code review
Aluerie Jan 23, 2024
728fa0e
⛔Remove Steam NonSense
Aluerie Jan 24, 2024
f96967f
🔨Fix bad enum namings
Aluerie Jan 24, 2024
494bd5c
🪓 Total Overhaul of the PR
Aluerie Jan 24, 2024
f8bd9b6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 24, 2024
2e9383f
🖋️Small doc edit
Aluerie Jan 24, 2024
da096d4
🆘Apply suggestions from code review by Gobot
Aluerie Jan 25, 2024
ab90872
🩺 More feedback corrections
Aluerie Jan 25, 2024
c07dff9
🪿Remove `fmt: off` from betterproto Enums
Aluerie Jan 25, 2024
dd1b731
🤺Quotes ' -> "
Aluerie Jan 25, 2024
db78cd0
🪥 Few more brush ups
Aluerie Jan 25, 2024
8ec073f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 25, 2024
3c89f4a
🪥and more
Aluerie Jan 25, 2024
e353b49
📺LiveMatchPlayer should subclass Partial user
Aluerie Jan 25, 2024
49ac537
🦸‍♀️heroes property for LiveMatch
Aluerie Jan 25, 2024
9fd115f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 25, 2024
aa7433b
🤧fix import * abd `__all__`
Aluerie Jan 25, 2024
8561fcb
Merge branch 'introduce-ext.dota2' of https://github.com/Aluerie/stea…
Aluerie Jan 25, 2024
59bf6fd
🔣Doc String + Remove C prefix
Aluerie Jan 25, 2024
037355f
📈 Glicko Rating and Behavior Summary
Aluerie Jan 27, 2024
5a19a1d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 27, 2024
7e3ddb1
💥MatchDetails, MM stats, rating - very raw
Aluerie Feb 3, 2024
3b83928
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 3, 2024
b4bd089
Merge branch 'Gobot1234:main' into introduce-ext.dota2
Aluerie Sep 21, 2024
69d0c92
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 21, 2024
bd12ec8
Merge branch 'Gobot1234:main' into introduce-ext.dota2
Aluerie Sep 21, 2024
517e33f
🏅Implement RankTier Medals
Aluerie Sep 24, 2024
04fcdef
🔬Introduce Match Minimal
Aluerie Sep 29, 2024
5d50888
📂Divide `models.py` into a folder
Aluerie Sep 30, 2024
38a8f39
Create models.py
Aluerie Sep 30, 2024
702f883
🧓Match History
Aluerie Sep 30, 2024
f553a8d
📲Social Feed Post Message
Aluerie Sep 30, 2024
bfef6bd
🪥Some Brush-ups
Aluerie Sep 30, 2024
da9d459
〽️Instantiate Partial Match
Aluerie Sep 30, 2024
8d166c3
🖼️Profile Request
Aluerie Sep 30, 2024
37a8fa7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 30, 2024
55f0486
Doc Edits
Aluerie Sep 30, 2024
87e9220
Merge branch 'introduce-ext.dota2' of https://github.com/Aluerie/stea…
Aluerie Sep 30, 2024
39f907f
🔮Refactor things back to proper state -> models
Aluerie Oct 2, 2024
047da1f
🔝Separate state for TopSource too
Aluerie Oct 2, 2024
6abe799
🦜Separate state for MM stats
Aluerie Oct 2, 2024
12c6df1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 2, 2024
e47e624
🌐 `replay_url`, `metadata_url`
Aluerie Oct 2, 2024
4a54ad1
🙂Add Facets to protos
Aluerie Oct 3, 2024
f465544
🎶Fix Match History
Aluerie Oct 7, 2024
1a96c93
🆕Add Kez hero
Aluerie Nov 22, 2024
f8f9e4a
🪥`timeout` keyword arg for some state methods
Aluerie Dec 31, 2024
5319c4b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 31, 2024
031fef9
Merge branch 'Gobot1234:main' into introduce-ext.dota2
Aluerie Dec 31, 2024
186fe70
Bump typing-extensions from 4.10.0 to 4.12.2
Aluerie Jan 29, 2025
501c0f1
Revert "Bump typing-extensions from 4.10.0 to 4.12.2"
Aluerie Jan 31, 2025
e37e82c
Merge branch 'Gobot1234:main' into introduce-ext.dota2
Aluerie Jan 31, 2025
dadcebb
⚒️Rename `instantiate` to `create` methods
Aluerie Mar 26, 2025
c778eb8
🪥Remove parameter `timeout`
Aluerie Mar 31, 2025
bf1ddb1
🪥Names probably should be adjective+noun style
Aluerie Mar 31, 2025
a4a8e63
🪥Use `lambda` instead of `partial`
Aluerie Mar 31, 2025
1515ccf
🆕Initial impl for `BaseMatch` and `BasePlayer`
Aluerie Mar 31, 2025
3030bcf
Update models.py
Aluerie Mar 31, 2025
ebed275
🔙Revert `partial`->`lambda` change
Aluerie Apr 1, 2025
1acded2
🪥Use `get_partial_user` over direct user constract
Aluerie Apr 1, 2025
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
28 changes: 28 additions & 0 deletions docs/ext/dota2/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.. currentmodule:: steam.ext.dota2

API Reference
===============

The following section outlines the API of steam.py's Dota 2 extension module.


Client
------

.. attributetable:: Client

.. autoclass:: Client
:members:
:inherited-members:

Bot
----

``ext.dota2`` also provides a :class:`Bot` class, which is a subclass of :class:`Client` and :class:`steam.ext.commands.Bot`.

.. attributetable:: steam.ext.dota2.Bot

.. autoclass:: steam.ext.dota2.Bot
:members:
:inherited-members:

11 changes: 11 additions & 0 deletions docs/ext/dota2/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(steam-ext-dota2)=

# `steam.ext.dota2` - A Team Fortress 2 Game Coordinator client

This extension offers the ability to interact with the Dota 2 Game Coordinator (Dota 2 GC)

```{toctree}
:maxdepth: 2

api
```
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ steam API Reference <api>
steam.ext.commands API Reference <ext/commands/api.rst>
steam.ext.csgo API Reference <ext/csgo/api.rst>
steam.ext.tf2 API Reference <ext/tf2/api.rst>
steam.ext.dota2 API Reference <ext/dota2/api.rst>
```

## Extensions
Expand All @@ -41,4 +42,5 @@ steam.py has extension modules to help with common tasks.
ext/commands/index.rst
ext/csgo/index.rst
ext/tf2/index.rst
ext/dota2/index.rst
```
10 changes: 10 additions & 0 deletions steam/ext/dota2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""
steam.ext.dota2
~~~~~~~~~~~~~~

A library for interacting with the Dota 2 Game Coordinator.

Licensed under The MIT License (MIT) - Copyright (c) 2020-present James H-B. See LICENSE
"""

from .client import *
127 changes: 127 additions & 0 deletions steam/ext/dota2/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
"""Licensed under The MIT License (MIT) - Copyright (c) 2020-present James H-B. See LICENSE"""

from __future__ import annotations

import asyncio
from typing import Final, Literal

from ..._const import timeout
from ..._gc import Client as Client_
from ...app import DOTA2
from ...ext import commands
from ...utils import MISSING
from .protobufs.dota_gcmessages_client_watch import (
CMsgClientToGCFindTopSourceTVGames,
CMsgGCToClientFindTopSourceTVGamesResponse,
)
from .state import GCState # noqa: TCH001

__all__ = (
"Client",
"Bot",
)


class Client(Client_):
"""Represents a client connection that connects to Steam. This class is used to interact with the Steam API, CMs
and the Dota 2 Game Coordinator.

:class:`Client` is a subclass of :class:`steam.Client`, so whatever you can do with :class:`steam.Client` you can
do with :class:`Client`.
"""

_APP: Final = DOTA2
_state: GCState # type: ignore # PEP 705

async def fetch_top_source_tv_games(
self,
*,
search_key: str = MISSING,
league_id: int = MISSING,
hero_id: int = MISSING,
start_game: Literal[0, 10, 20, 30, 40, 50, 60, 70, 80, 90] = 0,
game_list_index: int = MISSING,
lobby_ids: list[int] = MISSING,
) -> list[CMsgGCToClientFindTopSourceTVGamesResponse]:
"""Fetch Top Source TV Games.

This functionality is similar to game list in the Watch Tab of Dota 2 game application.
It fetches summary data for the currently on-going Dota 2 matches from the following categories:

* tournament games
* highest average mmr games
* specific lobbies, like friends' games by their lobby_ids

Note
-------
Note that the following documentation for keyword arguments to query against is rather observant
than from official. So, please, if you know more or description is incorrect, contact us.

Parameters
----------
search_key : :class: `str`, optional
Unknown purpose.
league_id : :class: `int`, optional
`league_id` for the professional tournament.
hero_id : :class: `int`, optional
`hero_id` to filter results by, just like in-client Watch Tab feature.
start_game : :class: `Literal[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]`, optional, by default 0
This argument controls how many responses the game coordinator should return.
For example, `start_game=0` returns a list with 1 Response,
`start_game=90` returns a list of 10 Responses.
Game coordinator fills each response in consequent manner with games that satisfy keyword arguments
or with currently live highest average MMR games in case no other argument was given.
game_list_index : :class: `int`, optional
Only get responses matching `game_list_index`. Responses from Game Coordinator change
from time to time. The `game_list_index` indicates that those responses belong to the same chunk.
lobby_ids : :class: `list[int]`, optional
Lobby ids to query against.

Returns
-------
list[dota_gcmessages_client_watch.CMsgGCToClientFindTopSourceTVGamesResponse]
The list of responses from Dota 2 Coordinator.
Those are grouped into grouped into chunks of 10 games.

Raises
------
asyncio.TimeoutError
Request time-outed. The reason for this might be inappropriate combination of keyword arguments,
inappropriate argument values or simply Dota 2 Game Coordinator being down.
"""
kwargs = locals()
kwargs.pop("self")
kwargs = {key: value for key, value in kwargs.items() if value is not MISSING}

def start_game_check(start_game: int):
def predicate(msg: CMsgGCToClientFindTopSourceTVGamesResponse) -> bool:
return msg.start_game == start_game

return predicate

futures = [
self._state.ws.gc_wait_for(
CMsgGCToClientFindTopSourceTVGamesResponse,
check=start_game_check(game_counter),
)
for game_counter in list(range(0, start_game + 1, 10))
]

await self._state.ws.send_gc_message(CMsgClientToGCFindTopSourceTVGames(**kwargs))

try:
async with timeout(30.0):
return await asyncio.gather(*futures)
except asyncio.TimeoutError:
raise asyncio.TimeoutError(
"Request time-outed. The reason might be inappropriate combination of keyword arguments, "
+ "inappropriate argument values or simply Dota 2 Game Coordinator being down."
)


class Bot(commands.Bot, Client):
"""Represents a Steam bot.

:class:`Bot` is a subclass of :class:`~steam.ext.commands.Bot`, so whatever you can do with
:class:`~steam.ext.commands.Bot` you can do with :class:`Bot`.
"""
10 changes: 10 additions & 0 deletions steam/ext/dota2/protobufs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import Final

import betterproto

APP_ID: Final = 570

from ....protobufs.msg import GCProtobufMessage
from . import dota_gcmessages_client_watch as dota_gcmessages_client_watch, gcsdk_gcmessages as gcsdk_gcmessages

[setattr(cls, "_betterproto", betterproto.ProtoClassMetadata(cls)) for cls in GCProtobufMessage.__subclasses__()]
Loading