Code Monkey home page Code Monkey logo

steam's Introduction

Latest version released on PyPi Latest release on Github PyPI - Python Version MIT License
Test coverage Build status of master branch Documentation status
SonarCloud Rating SonarCloud Rating SonarCloud Rating

A python module for interacting with various parts of Steam.

Supports Python 2.7+ and 3.4+.

Documentation: http://steam.readthedocs.io/en/latest/

Features

  • SteamClient - communication with the steam network based on gevent.
  • CDNClient - access to Steam content depots
  • WebAuth - authentication for access to store.steampowered.com and steamcommunity.com
  • WebAPI - simple API for Steam's Web API with automatic population of interfaces
  • SteamAuthenticator - enable/disable/manage two factor authentication for Steam accounts
  • SteamID - convert between the various ID representations with ease
  • Master Server Query Protocol - query masters servers directly or via SteamClient

Checkout the User guide for examples, or the API Reference for details.

For questions, issues or general curiosity visit the repo at https://github.com/ValvePython/steam.

Like using the command line? Try steamctl tool

Install

For system specific details, see Installation Details.

Install latest release version from PYPI:

# with SteamClient dependecies
pip install -U "steam[client]"

# without (only when using parts that do no rely on gevent, and protobufs)
pip install -U steam

Installing directly from github repository:

# cutting edge from master
pip install "git+https://github.com/ValvePython/steam#egg=steam"

# specific version tag (e.g. v1.0.0)
pip install "git+https://github.com/ValvePython/[email protected]#egg=steam[client]"
# without SteamClient extras
pip install "git+https://github.com/ValvePython/[email protected]#egg=steam"

Vagrant

The repo includes a Vagrantfile to setup enviroment for expermentation and development. We assume you've already have vagrant and virtualbox set up. The VM is Ubuntu 16.04 with all necessary packages installed, and virtualenv for python2 and python3.

vagrant up    # spin the VM and let it setup
vagrant ssh
# for python2
$ source venv2/bin/activate
# for python3
$ source venv3/bin/activate

Local Testing

To run the test suite with the current python, use

make test

To run for specific version, setup a virtual environment

virtualenv -p python3 py3
source py3/bin/active
pip install -r requirements.txt
make test

Contact

IRC: irc.libera.chat / #steamre (join via webchat)

steam's People

Contributors

alec-hs avatar aquaismissing avatar drizbit avatar encryptedkitten avatar hexiro avatar int3l avatar lablazer avatar lopezloo avatar melvyn2 avatar notjosh avatar nukeop avatar offish avatar philippj avatar pinkdraconian avatar rossengeorgiev avatar sammiee5311 avatar sleepprogger avatar smcv avatar tjensen avatar xfxf avatar xpaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

steam's Issues

MsgProto based on EconTrading_InitiateTradeRequest doesn't have body matched properly

It looks like that when you are creating MsgProto(EMsg.EconTrading_InitiateTradeRequest) and other objects based on EMsg.EconTrading they don't have a body, instead they have the !!! NO BODY!!! string, and as far as I know, these msg's should have body.other_steamid attribute.
What's more, the problem seems to dissapear when you rename Emsg.EconTrading_InitiateTradeRequest into Emsg.Trading_InitiateTradeRequest.

Maybe I'm wrong, but I think that it would be nice if you could take a look at this issue.

TOTP and SteamAuthenticator

Tasks:

  • steam totp code generation, confirmation key generation, time sync
  • process for adding/removing authenticator on an account
    • Over WebAPI
      • implement a way of obtaining mobile oauth token (#30)
    • Over Unified Messages
  • consider implementing a standard way to encrypt and store authenticator secrets

Twofactor code issue for webauthentication

When trying to create a session for trading i encouter a weird bug where steam doesnt accept the twofactorcode when requesting 'https://store.steampowered.com/login/dologin/'.

My code

web = steam.webauth.WebAuth(accountDetails['loginInformation']['username'], accountDetails['loginInformation']['password'])

try:
    web.login()
except steam.webauth.TwoFactorCodeRequired:
    web.login(twofactor_code=custom.Steam2FA(accountDetails['identitySecret']).getCode())
except Exception, e:
    print 'Could not log into steam web. %s' % e
else:
    history = web.session.get('https://store.steampowered.com/account/history/')

    print history.text

The 2FA code is working but i still raises the steam.webauth.TwoFactorCodeRequired exception.

Request
{'username': 'XXXXX', 'remember_login': False, 'rsatimestamp': u'115481000000', 'loginfriendlyname': 'python-steam webauth', 'emailauth': '', 'donotcache': 146425112103940, 'password': 'XXXXXXXX', 'emailsteamid': '', 'captcha_text': '', 'twofactorcode': 'XXXXX', 'captchagid': -1}

Response
{u'requires_twofactor': True, u'message': u'', u'clear_password_field': True, u'success': False}

I checked the request data with a live request via chrome and the supplied form data is the same.

Implement mobile auth

As the title says, it would be nice to have WebAuth with access to mobile pages, for trade confirmations etc.

A copy of WebAuth would be required with some uri and cookie changes.

I already worked on this and made a "fully working" prototype based on WebAuth.

http://pastebin.com/2bRpaKu1

Writing, loading and sending sentry files not working

Hi

Looks like the client won't write and/or load and send sentry files automatically.

_handle_update_machine_auth is bound to be called on EMsg.ClientUpdateMachineAuth event but it looks like it's never triggered.

Is it not implemented yet or expected to work?

SteamAuthenticator improvements

Task:

  • consider renaming various methods to make the api more clear
  • helper functions for fetching secrets from an android device

Python 3 support

The follow modules are needed for full python 3 support:

  • gevent 1.1
  • protobuf 3.0.0

CMClient: Refactor reconnection code

It's best to leave reconnection logic to the application, however there are certain cases where it seems better to automatically reconnect/retry.

  • Trying to connect to CM, but timing out during connect()

Currently considering removing automatic reconnect, except for while trying connect(), and providing a reconnect method that will do exponential backoff. This way the application can then just do:

client.on('disconnect', client.reconnect)

reconnect will essentially be connect with delay. The delay will be reset on successful login.

Replace pycrypto as it is no longer being supported

Seems that development of pycryptohas stopped. Last commit on the repo is from Jun, 2014.
It maybe worth looking into replacing with cryptography, which supports newer versions of python.

Tasks:

  • replace in core.crypto
  • replace in WebAuth
  • update dependencies

SteamAuthenticator.get_confirmation_key wrong parameter order

get_confirmation_key calls generate_confirmation_key with the parameters in following order: identity_secret, tag, time.

generate_confirmation_key parameter order is identity_secret, time, tag

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Users\\PyCharmProjects\steam\steam\confirmations.py", line 46, in fetch_confirmations
    confirmation_key = self._authenticator.get_confirmation_key('conf', timestamp)
  File "C:\Users\\PyCharmProjects\steam\steam\guard.py", line 105, in get_confirmation_key
    self.get_time() if timestamp is None else timestamp)
  File "C:\Users\\PyCharmProjects\steam\steam\guard.py", line 313, in generate_confirmation_key
    data = struct.pack('>Q', int(timestamp)) + tag.encode('ascii') # this will NOT stop working in 2038
ValueError: invalid literal for int() with base 10: 'conf'

Add more recipes/examples

It will be useful to have more recipies of how to use various functionalities of the library.
This would be the place to suggest possible use cases and do my best to get provide a nice clean recipe for them.

  • SteamClient login
  • Bulding a simple web api
  • Setup and use for SteamAuthenticator
  • WebAuth login and use (the docs have one)
  • More complex example of various SteamClient builtin APIs

Implement CDN Client

This means authentication and access to the CDN network to make possible the download of app content

  • authentication
  • manifest download and decryption
  • download of chunks and decryption

Things needed in SteamClient

  • fetching app, package and depot info
  • getting a list of content servers

Add protobuf messages to docs

There are a few advantages of having protobuf message in docs:

  • can be searched easily
  • can be referenced inside the docs easily
  • can be linked to using URls

Possible problems:

  • too verbose, there are many messages
  • each message might include properties related to protobuf descriptors, which is not needed

How we can send message & delete friend friends ?

message = MsgProto(EMsg.ClientAddFriend)
message.body.steamid_to_add = userid
resp = client.send_message_and_wait(message, EMsg.ClientAddFriendResponse)

This is enought to send friend requests but i cant find any document how to send message from my friendlist & delete friends my list.I did read almost all documentation, did i miss something ? Some help would be great.

Group API

Is there any way to retrieve information from groups? Thanks.

Implement remember password

Client receives a new login key after logon that can be used for subsequent logins instead of the password. Login with a login key will not require 2FA code.

> ClientNewLoginKey
< ClientNewLoginKeyAccepted

Introduce delay when reconnecting automatically

steam/steam/core/cm.py

Lines 290 to 295 in 90e1a55

if result in (EResult.TryAnotherCM,
EResult.ServiceUnavailable
):
self.servers.mark_bad(self.current_server_addr)
self.disconnect(True)
return

During maintenance the client will spam reconnect servers without any delay.
Best to introduce exponential backoff to up to 30s to handle such situations.

Implement adding phone number in SteamAuthenticator

It would be nice to add phone number using SteamAuthenticator, but it needs sessionid.
We can get sessionid in something like that

def get_sessionid(mobile_session):
    headers = {
        'X-Requested-With' : 'com.valvesoftware.android.steam.community',
        'referer' : 'https://steamcommunity.com/mobilelogin?oauth_client_id=DE45CD61&\
            oauth_scope=read_profile%20write_profile%20read_client%20write_client'
    }
    mobile_session.session.get('https://steamcommunity.com/login?oauth_client_id=DE45CD61&\
                oauth_scope=read_profile%20write_profile%20read_client%20write_client',
                headers=headers, timeout=15)
    sessionid = mobile_session.session.cookies['sessionid']
    return sessionid

where 'session' is WebAuth object
and add phone number in that way (it may be better, but I'm not good in coding):

class PhoneLinker:
    def __init__(self, medium=None):
        self.phone_number = None
        self.sessionid = medium.session.cookies['sessionid'] \
                if 'sessionid' in medium.session.cookies \
                else get_sessionid(medium)
        self._ajaxurl = 'https://steamcommunity.com/steamguard/phoneajax'
        if isinstance(medium, MobileWebAuth):
            if not medium.complete:
                raise SteamAuthenticatorError("MobileWebAuth instance not logged in")
            self.medium = medium
                        
    def _has_phone_attached(self):
        if not self.medium:
            return None
        post_data = {
            'op' : 'has_phone',
            'arg' : 'null',
            'sessionid' : self.medium.session.cookies['sessionid']
        }
        resp = self.medium.session.post(self._ajaxurl, post_data, timeout=15)
        return resp.json()['has_phone']
        
    def add_phone_number(self, phone_number=None):
        if not self.phone_number and phone_number:
            phone_number = phone_number.replace('-','').replace('(','').replace(')','')
            if not phone_number or len(phone_number) < 10:
                return False
            if phone_number[0] != '+':
                return False
            self.phone_number = phone_number
        elif not self.phone_number and not phone_number:
            return False
        post_data = {
            'op' : 'add_phone_number',
            'arg' : self.phone_number,
            'sessionid' : self.medium.session.cookies['sessionid']
            }
        resp = self.medium.session.post(self._ajaxurl, post_data, timeout=15)
        if not resp:
            return False
        return resp.json()['success']

Can this be added in SteamAuthenticator class?

Documentation

So far, the module has been very simple. This is going to change going forward with the introduction of SteamClient. It would be best to setup a way to create documentation, possibly using sphinx.

OverflowError: Python int too large to convert to C long

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/steam/client/__init__.py", line 341, in anonymous_login
    message.header.steamid = SteamID(type='AnonUser', universe='Public')
  File "/usr/lib/python2.7/site-packages/steam/steamid.py", line 43, in __new__
    return super(SteamID, cls).__new__(cls, steam64)
OverflowError: Python int too large to convert to C long

Happens under python2.7 32bit and not in 64bit.

Best to conditionally subclass at runtime from long for py2 and int for py3.
Need to verify that long won't cause problems when assigning to protobuf properties.

No module named webauth

I'm very sorry for newb question, but can you put me in right direction on how to find what causes the problem? I'm using python 2.7.

>>> import steam
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "steam.py", line 2, in <module>
    import steam.webauth as wa
ImportError: No module named webauth

Implement Chat for SteamClient

Tasks:

  • SteamUser rework
  • research user to user chat protocol
  • implement user to user chat handling
  • research group chat protocol
  • implement group protocol messages
  • implement group chat
  • docs & examples

Cli example

http://steam.readthedocs.io/en/stable/user_guide.html#cli-example

Traceback (most recent call last):
File "test3.py", line 14, in <module>
client = SteamClient()
File "/usr/local/lib/python2.7/dist-packages/steam/__init__.py", line 16, in __new__
from steam.client import SteamClient as SC
File "/usr/local/lib/python2.7/dist-packages/steam/client/__init__.py", line 22, in <module>
from eventemitter import EventEmitter
File "/usr/local/lib/python2.7/dist-packages/eventemitter/__init__.py", line 3, in <module>
from .emitter import EventEmitter
File "/usr/local/lib/python2.7/dist-packages/eventemitter/emitter.py", line 11
async def _try_catch_coro(emitter, event, listener, coro):
^
SyntaxError: invalid syntax
`

System : Linux b 4.0.0-kali1-686-pae #1 SMP Debian 4.0.4-1+kali2 (2015-06-03) i686 GNU/Linux
Python : 2.x

Implement Rich Presence

  • upload rich presense (serialize bin vdf)
  • SteamUser property for rich presence (deserialize bin vdf)
  • requesting user's rich presence

Facts

  • Rich presence messages make use of routing_app field in the message header. The appid should be used to separate RPs of different games.

  • steamid_broadcast - list of steamids to which the rich presence will be broadcasted, usually friends who are in the same game

  • RPs can contain proto message serialized in proto text format. Dota 2 has some for when the player is in a party or lobby

    • Parse text with google.protobuf.text_format.Merge(text, message)
    • Serialize to text with google.protobuf.text_format.MessageToString(message)

WebAuth module

This module will implement the web auth login process. Should be useful when application only targets steam web pages. Otherwise, it has to use the steam client to get a web session.

  • implement WebAuth
  • WebAuth docs
  • tests

EMsg.ClientFriendsList event not calling registered callbacks in SteamClient

Hi

I started porting a little steam chatbot from C# SteamKit to python recently.

I'm trying to get a list of friends after logging in - according to logs SteamClient instance receives the relevant event:

Incoming: <MsgProto <EMsg.ClientFriendsList: 767>>
Emit event: <EMsg.ClientFriendsList: 767>

But it doesn't trigger the callback, which I'm registering like this:

def __init__(self):
    self.client.on(EMsg.ClientFriendsList, self.on_client_friends_list)

def on_client_friends_list(self, msg):
        logger.info("Received ClientFriendsList")
        logger.info(msg)

There is more code but that's the gist of it - the bottom line is that if I do the same with, say EMsg.ClientAccountInfo, it calls the registered callback.

Any advice?

'!!! NO BODY !!!' for some MsgProto() objects

Hello.
When I trying to make objects, like
MsgProto(EMsg.ClientCreateAccountProto) or MsgProto(EMsg.ClientCreateAccountProtoResponse),
body of these objects has only '!!! NO BODY !!!'.
So I have to write some weird things:
a.body = steammessages_clientserver_2_pb2.CMsgClientCreateAccount()
But I can't get response because it's have '!!! NO BODY !!!', too.
get_cmsg() with some EMsg's return None.
Is it my mistake or something else?
And what does '!!! NO BODY !!!' means?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.