def test_proto_from_dict_merge(self): self.msg.list_number32.extend([1, 2, 3]) ut.proto_fill_from_dict(self.msg, {'list_number32': [4, 5, 6]}, clear=False) self.assertEqual(self.msg.list_number32, [4, 5, 6])
def send(self, message, params=None): """Send service method request :param message: proto message instance (use :meth:`SteamUnifiedMessages.get`) or method name (e.g. ``Player.GetGameBadgeLevels#1``) :type message: :class:`str`, proto message instance :param params: message parameters :type params: :class:`dict` :return: ``jobid`` event identifier :rtype: :class:`str` Listen for ``jobid`` on this object to catch the response. .. note:: If you listen for ``jobid`` on the client instance you will get the encapsulated message """ if isinstance(message, str): message = self.get(message) if message not in self._data: raise ValueError("Supplied message is invalid. Use 'get' method.") if params: proto_fill_from_dict(message, params) capsule = MsgProto(EMsg.ClientServiceMethod) capsule.body.method_name = self._data[message] capsule.body.serialized_method = message.SerializeToString() return self._steam.send_job(capsule)
def _send(self, emsg, data={}, proto=None, jobid=None): if not isinstance(data, dict): raise ValueError("data kwarg can only be a dict") if proto is None: proto = find_proto(emsg) if not issubclass(proto, google.protobuf.message.Message): raise ValueError("Unable to find proto for emsg, or proto kwarg is invalid") message = proto() proto_fill_from_dict(message, data) header = GCMsgHdrProto(emsg) if jobid is not None: header.proto.job_id_source = jobid if self.verbose_debug: str_message = '' str_header = str(header) str_body = str(message) if str_header: str_message += "-- header ---------\n%s\n" % str_header if str_body: str_message += "-- message --------\n%s\n" % str_body self._LOG.debug("Outgoing: %s\n%s" % (repr(emsg), str_message)) else: self._LOG.debug("Outgoing: %s", repr(emsg)) GameCoordinator.send(self, header, message.SerializeToString())
def _send(self, emsg, data={}, proto=None, jobid=None): if not isinstance(data, dict): raise ValueError("data kwarg can only be a dict") if proto is None: proto = find_proto(emsg) if not issubclass(proto, google.protobuf.message.Message): raise ValueError( "Unable to find proto for emsg, or proto kwarg is invalid") message = proto() proto_fill_from_dict(message, data) header = GCMsgHdrProto(emsg) if jobid is not None: header.proto.job_id_source = jobid if self.verbose_debug: str_message = '' str_header = str(header) str_body = str(message) if str_header: str_message += "-- header ---------\n%s\n" % str_header if str_body: str_message += "-- message --------\n%s\n" % str_body self._LOG.debug("Outgoing: %s\n%s" % (repr(emsg), str_message)) else: self._LOG.debug("Outgoing: %s", repr(emsg)) GameCoordinator.send(self, header, message.SerializeToString())
def send_um(self, method_name, params=None): """Send service method request :param method_name: method name (e.g. ``Player.GetGameBadgeLevels#1``) :type method_name: :class:`str` :param params: message parameters :type params: :class:`dict` :return: ``job_id`` identifier :rtype: :class:`str` Listen for ``jobid`` on this object to catch the response. """ proto = get_um(method_name) if proto is None: raise ValueError("Failed to find method named: %s" % method_name) message = MsgProto(EMsg.ServiceMethodCallFromClient) message.header.target_job_name = method_name message.body = proto() if params: proto_fill_from_dict(message.body, params) return self.send_job(message)
def send(self, message, params=None): """Send service method request :param message: proto message instance (use :meth:`SteamUnifiedMessages.get`) or method name (e.g. ``Player.GetGameBadgeLevels#1``) :type message: :class:`str`, proto message instance :param params: message parameters :type params: :class:`dict` :return: ``jobid`` event identifier :rtype: :class:`str` Listen for ``jobid`` on this object to catch the response. .. note:: If you listen for ``jobid`` on the client instance you will get the encapsulated message """ if isinstance(message, str): message = self.get(message) if message not in self._data: raise ValueError("Supplied message seems to be invalid. Did you use 'get' method?") if params: proto_fill_from_dict(message, params) capsule = MsgProto(EMsg.ClientServiceMethod) capsule.body.method_name = self._data[message] capsule.body.serialized_method = message.SerializeToString() return self._steam.send_job(capsule)
def test_proto_fill_from_dict__func_generator(self): def number_gen(): yield 1 yield 2 yield 3 ut.proto_fill_from_dict(self.msg, {'list_number32': number_gen()}) self.assertEqual(self.msg.list_number32, [1,2,3])
def test_proto_from_dict_merge_dict(self): self.msg.messages.add(text='one') self.msg.messages.add(text='two') ut.proto_fill_from_dict(self.msg, {'messages': [{'text': 'three'}]}, clear=False) self.assertEqual(len(self.msg.messages), 1) self.assertEqual(self.msg.messages[0].text, 'three')
def test_proto_fill_from_dict__func_generator(self): def number_gen(): yield 1 yield 2 yield 3 ut.proto_fill_from_dict(self.msg, {'list_number32': number_gen()}) self.assertEqual(self.msg.list_number32, [1, 2, 3])
def get_product_info(self, apps=[], packages=[], timeout=15): """Get product info for apps and packages :param apps: items in the list should be either just ``app_id``, or :class:`dict` :type apps: :class:`list` :param packages: items in the list should be either just ``package_id``, or :class:`dict` :type packages: :class:`list` :return: dict with ``apps`` and ``packages`` containing their info, see example below :rtype: :class:`dict`, :class:`None` .. code:: python {'apps': {570: {...}, ...}, 'packages': {123: {...}, ...} } """ if not apps and not packages: return message = MsgProto(EMsg.ClientPICSProductInfoRequest) for app in apps: app_info = message.body.apps.add() app_info.only_public = False if isinstance(app, dict): proto_fill_from_dict(app_info, app) else: app_info.appid = app for package in packages: package_info = message.body.packages.add() if isinstance(package, dict): proto_fill_from_dict(package_info, package) else: package_info.packageid = package message.body.meta_data_only = False job_id = self.send_job(message) data = dict(apps={}, packages={}) while True: chunk = self.wait_event(job_id, timeout=timeout, raises=True) chunk = chunk[0].body for app in chunk.apps: data['apps'][app.appid] = vdf.loads(app.buffer[:-1].decode( 'utf-8', 'replace'))['appinfo'] for pkg in chunk.packages: data['packages'][pkg.packageid] = vdf.binary_loads( pkg.buffer[4:])[str(pkg.packageid)] if not chunk.response_pending: break return data
def test_proto_fill_from_dict__dict_func_generator(self): def dict_gen(): yield {'text': 'one'} yield {'text': 'two'} ut.proto_fill_from_dict(self.msg, {'messages': dict_gen()}) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')
def test_proto_fill_from_dict__dict_list(self): ut.proto_fill_from_dict( self.msg, {'messages': [{ 'text': 'one' }, { 'text': 'two' }]}) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')
def test_proto_fill_from_dict__dict_generator(self): ut.proto_fill_from_dict( self.msg, {'messages': (x for x in [{ 'text': 'one' }, { 'text': 'two' }])}) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')
def test_proto_from_dict_merge_dict(self): self.msg.messages.add(text='one') self.msg.messages.add(text='two') ut.proto_fill_from_dict(self.msg, {'messages': [{ 'text': 'three' }]}, clear=False) self.assertEqual(len(self.msg.messages), 1) self.assertEqual(self.msg.messages[0].text, 'three')
def test_proto_fill_from_dict__dict_filter(self): ut.proto_fill_from_dict(self.msg, { 'messages': filter(lambda x: True, [{ 'text': 'one' }, { 'text': 'two' }]) }) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')
def test_proto_from_dict_to_dict(self): DATA = { 'buffers': [{ 'data': b'some data', 'flags': [{ 'flag': True }, { 'flag': False }, { 'flag': False }] }, { 'data': b'\x01\x02\x03\x04', 'flags': [{ 'flag': False }, { 'flag': True }, { 'flag': True }] }], 'list_number32': [ 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824 ], 'list_number64': [ 4, 64, 1024, 16384, 262144, 1125899906842624, 18014398509481984, 288230376151711744, 4611686018427387904 ], 'messages': [{ 'text': 'test string' }, { 'text': 'another one' }, { 'text': 'third' }], 'number32': 16777216, 'number64': 72057594037927936 } ut.proto_fill_from_dict(self.msg, DATA) RESULT = ut.proto_to_dict(self.msg) self.assertEqual(DATA, RESULT)
def send(self, message, body_params=None): """Send a message to CM :param message: a message instance :type message: :class:`.Msg`, :class:`.MsgProto` :param body_params: a dict with params to the body (only :class:`.MsgProto`) :type body_params: dict """ if not self.connected: self._LOG.debug("Trying to send message when not connected. (discarded)") else: if body_params and isinstance(message, MsgProto): proto_fill_from_dict(message.body, body_params) CMClient.send(self, message)
def send(self, message, body_params=None): """.. versionchanged:: 0.8.4 Send a message to CM :param message: a message instance :type message: :class:`.Msg`, :class:`.MsgProto` :param body_params: a dict with params to the body (only :class:`.MsgProto`) :type body_params: dict """ if not self.connected: self._LOG.debug("Trying to send message when not connected. (discarded)") else: if body_params and isinstance(message, MsgProto): proto_fill_from_dict(message.body, body_params) CMClient.send(self, message)
def test_proto_from_dict_to_dict(self): DATA = {'buffers': [ {'data': b'some data', 'flags': [{'flag': True}, {'flag': False}, {'flag': False}]}, {'data': b'\x01\x02\x03\x04', 'flags': [{'flag': False}, {'flag': True}, {'flag': True}]} ], 'list_number32': [4,16,64,256,1024,4096,16384,65536,262144,1048576,4194304,16777216,67108864,268435456,1073741824], 'list_number64': [4,64,1024,16384,262144,1125899906842624,18014398509481984,288230376151711744,4611686018427387904], 'messages': [{'text': 'test string'}, {'text': 'another one'}, {'text': 'third'}], 'number32': 16777216, 'number64': 72057594037927936 } ut.proto_fill_from_dict(self.msg, DATA) RESULT = ut.proto_to_dict(self.msg) self.assertEqual(DATA, RESULT)
def change_status(self, **kwargs): """ Set name, persona state, flags .. note:: Changing persona state will also change :attr:`persona_state` :param persona_state: persona state (Online/Offlane/Away/etc) :type persona_state: :class:`.EPersonaState` :param player_name: profile name :type player_name: :class:`str` :param persona_state_flags: persona state flags :type persona_state_flags: :class:`.EPersonaStateFlag` """ if not kwargs: return self.persona_state = kwargs.get('persona_state', self.persona_state) message = MsgProto(EMsg.ClientChangeStatus) proto_fill_from_dict(message.body, kwargs) self.send(message)
def test_proto_from_dict__dict_insteadof_list(self): with self.assertRaises(TypeError): ut.proto_fill_from_dict(self.msg, {'list_number32': [{}, {}]})
def test_proto_fill_from_dict__filter(self): ut.proto_fill_from_dict(self.msg, {'list_number32': filter(lambda x: True, [1,2,3])}) self.assertEqual(self.msg.list_number32, [1,2,3])
def test_proto_fill_from_dict__filter(self): ut.proto_fill_from_dict( self.msg, {'list_number32': filter(lambda x: True, [1, 2, 3])}) self.assertEqual(self.msg.list_number32, [1, 2, 3])
def test_proto_fill_from_dict__dict_filter(self): ut.proto_fill_from_dict(self.msg, {'messages': filter(lambda x: True, [{'text': 'one'}, {'text': 'two'}])}) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')
def test_proto_fill_from_dict__list(self): ut.proto_fill_from_dict(self.msg, {'list_number32': [1,2,3]}) self.assertEqual(self.msg.list_number32, [1,2,3])
def test_proto_fill_from_dict__map(self): ut.proto_fill_from_dict(self.msg, {'list_number32': map(int, [1, 2, 3])}) self.assertEqual(self.msg.list_number32, [1, 2, 3])
def test_proto_fill_from_dict__dict_list(self): ut.proto_fill_from_dict(self.msg, {'messages': [{'text': 'one'}, {'text': 'two'}]}) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')
def test_proto_from_dict_merge(self): self.msg.list_number32.extend([1,2,3]) ut.proto_fill_from_dict(self.msg, {'list_number32': [4,5,6]}, clear=False) self.assertEqual(self.msg.list_number32, [4,5,6])
def test_proto_fill_from_dict__generator(self): ut.proto_fill_from_dict(self.msg, {'list_number32': (x for x in [1, 2, 3])}) self.assertEqual(self.msg.list_number32, [1, 2, 3])
def test_proto_fill_from_dict__list(self): ut.proto_fill_from_dict(self.msg, {'list_number32': range(10)}) self.assertEqual(self.msg.list_number32, list(range(10)))
def test_proto_from_dict__list_insteadof_dict(self): with self.assertRaises(TypeError): ut.proto_fill_from_dict(self.msg, {'messages': [1,2,3]})
def test_proto_from_dict__list_insteadof_dict(self): with self.assertRaises(TypeError): ut.proto_fill_from_dict(self.msg, {'messages': [1, 2, 3]})
def get_product_info(self, apps=[], packages=[], timeout=15): """Get product info for apps and packages :param apps: items in the list should be either just ``app_id``, or :class:`dict` :type apps: :class:`list` :param packages: items in the list should be either just ``package_id``, or :class:`dict` :type packages: :class:`list` :return: dict with ``apps`` and ``packages`` containing their info, see example below :rtype: :class:`dict`, :class:`None` .. code:: python {'apps': {570: {...}, ...}, 'packages': {123: {...}, ...} } When a token is needed to access the full info (e.g. branches and depots) the ``_missing_token`` will be set to ``True``. The token can be obtained by calling :meth:`get_access_tokens` if the account has a license. .. code:: python result = client.get_product_info(apps=[123]) if result['apps'][123]['_missing_token']: tokens = client.get_access_token(apps=[123]) result = client.get_product_info(apps={'appid': 123, 'access_token': tokens['apps'][123] }) """ if not apps and not packages: return message = MsgProto(EMsg.ClientPICSProductInfoRequest) for app in apps: app_info = message.body.apps.add() app_info.only_public = False if isinstance(app, dict): proto_fill_from_dict(app_info, app) else: app_info.appid = app for package in packages: package_info = message.body.packages.add() if isinstance(package, dict): proto_fill_from_dict(package_info, package) else: package_info.packageid = package message.body.meta_data_only = False job_id = self.send_job(message) data = dict(apps={}, packages={}) while True: chunk = self.wait_event(job_id, timeout=timeout, raises=True) chunk = chunk[0].body for app in chunk.apps: data['apps'][app.appid] = vdf.loads(app.buffer[:-1].decode('utf-8', 'replace'))['appinfo'] data['apps'][app.appid]['_missing_token'] = app.missing_token for pkg in chunk.packages: data['packages'][pkg.packageid] = vdf.binary_loads(pkg.buffer[4:])[str(pkg.packageid)] data['packages'][pkg.packageid]['_missing_token'] = pkg.missing_token if not chunk.response_pending: break return data
def test_proto_fill_from_dict__generator(self): ut.proto_fill_from_dict(self.msg, {'list_number32': (x for x in [1,2,3])}) self.assertEqual(self.msg.list_number32, [1,2,3])
def test_proto_fill_from_dict__dict_generator(self): ut.proto_fill_from_dict(self.msg, {'messages': (x for x in [{'text': 'one'}, {'text': 'two'}])}) self.assertEqual(len(self.msg.messages), 2) self.assertEqual(self.msg.messages[0].text, 'one') self.assertEqual(self.msg.messages[1].text, 'two')