Page 1 of 1

Working with ProtobufMessage

Posted: Wed Oct 26, 2016 3:57 pm
by iPlayer
Hey there,

I'm currently working with ProtobufMessage that TextMsg uses.

As you can see, the message and parameters added together form a params field in that buffer.

Question: how do I get message and params back?

Syntax: Select all

buffer.get_string('params')
crashes the server.

Thanks

P.S. Also, kinda disappointing that I have to import ProtobufMessage from _messages module, not messages

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 4:12 pm
by Ayuto
It's a repeated message. Thus, you have to use get_repeated_string().

I thought we have added checks to prevent crashes due to wrong usage, but it seems like we haven't. :grin:
I will see if I can add them when I get home at the weekend.

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 4:15 pm
by iPlayer
Well, I tried doing

Syntax: Select all

buffer.get_repeated_string('params', 0)

Syntax: Select all

buffer.get_repeated_string('params', 1)


- still crashes the server.

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 4:17 pm
by Ayuto
Did you set any params? Can you show me your test code?

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 4:22 pm
by iPlayer

Syntax: Select all

from core import PLATFORM
from engines.server import engine_server
from memory import Convention, DataType, get_object_pointer, make_object
from memory.hooks import PreHook
from _messages import ProtobufMessage
from messages import get_message_index


TEXTMSG_INDEX = get_message_index('TextMsg')


if PLATFORM == "windows":
SEND_USER_MESSAGE_INDEX = 45
else:
SEND_USER_MESSAGE_INDEX = 45


send_user_message = get_object_pointer(engine_server).make_virtual_function(
SEND_USER_MESSAGE_INDEX,
Convention.THISCALL,
[DataType.POINTER, DataType.POINTER, DataType.INT, DataType.POINTER],
DataType.VOID
)


@PreHook(send_user_message)
def pre_send_user_message(args):
if args[2] != TEXTMSG_INDEX:
return

buffer = make_object(ProtobufMessage, args[3])

print("TextMsg caught!")
print("params: {}".format(buffer.get_repeated_string('params', 0)))


Does it mean the game could send empty TextMsg's?

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 4:41 pm
by Ayuto
Hmm, I will need to do a few tests. Your code seems to be correct. Can you print other stuff like buffer.get_int32('msg_dst'), buffer.debug_string or buffer.name?

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 4:54 pm
by iPlayer
All of that crashed the server. Tested 3 times, separately.

buffer.size: 46


I must mention that removing attempts to obtain something from the buffer shows that TextMsg is sent several times during player connect. However I only need to hook #Game_connected message. What could other TextMsg's mean?

Edit: Couldn't get msg_name from SayText2 either. And it seems that my deadchat has stopped working. It also crashes the server.

Re: Working with ProtobufMessage

Posted: Wed Oct 26, 2016 9:25 pm
by iPlayer
Played around with SayText2 and it seems that it crashes only when the original message was sent by the game. Sending messages from SP allowed me to get msg_name field properly.
Also: in case of SP-started message, SP will report incorrect foobar field. But when the message is sent by the game, any attempt to get something from protobuf, be it valid or not, will result in a crash.

Re: Working with ProtobufMessage

Posted: Thu Oct 27, 2016 9:39 am
by L'In20Cible
https://github.com/Source-Python-Dev-Te ... 94a59e8410

EDIT: Okay, made more testing and this doesn't fix everything. Setting any fields will no longer cause a crash. However, getting string will cause one - I was testing with SayText2.chat so I didn't notice it until now. Will do further debugging to see if I can fix those too.

EDIT2: Everything seems to work fine on my side after this commit: https://github.com/Source-Python-Dev-Te ... 5893d11d90

Re: Working with ProtobufMessage

Posted: Thu Oct 27, 2016 3:42 pm
by iPlayer
That fixed the issue for me. Thanks in advance!