Modifying chat with sayfilter but SayCommand doesnt "register"

Please post any questions about developing your plugin here. Please use the search function before posting!
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Tue Mar 29, 2016 12:49 am

Hey,

I talked already to Ayuto about my problem but maybe you can help me out there.

So I'm modifying my chat currently with the SayFilter & coloring it and sending it modified out with SayText2, but my problem is when you CommandReturn.BLOCK the sayfilter (so the old message wont get shown) the SayCommand doesnt register anymore, so right now I need to write a decorator with player_say and hook every function with it, kinda stupid when you can use the awesome SayCommand's
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Mar 29, 2016 2:49 am

You can find out if a command is registered by SP using the command generator:
http://forums.sourcepython.com/showthread.php?191&p=6241&viewfull=1#post6241

So, my suggestion would be to not change the text in the say filter if the command is in SayCommandGenerator().
Image
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Postby decompile » Tue Mar 29, 2016 11:44 am

That will work, but Isnt there another way so I can modify the chat with colors even when the player writes a command?
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Mar 29, 2016 12:30 pm

The only other way that I can think of would be to hook the user message itself instead of using a say filter.
http://forums.sourcepython.com/showthread.php?980

We still do not have a built-in way to do this, though it is still planned.
Image
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Tue Mar 29, 2016 1:46 pm

Is there a way to dispatch a command to CSayCommandManager from python though? If there were, it would be possible to block the string, but if the string is present in the command generator, we would dispatch it to the command manager so that it will call its callbacks.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Mar 29, 2016 2:03 pm

We could add that in, but it would only help in the case where commands were registered by SP. Meaning that if a server also uses SourceMod, it would still block any commands registered with SM. The cleanest way would be to hook SayText2, get the msg_name, and override it if the message is a normal chat message. That would also help to keep the same RecipientFilter on say_team as well as dead/spec player chat.
Image
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Tue Mar 29, 2016 2:07 pm

No, please don't add that in, that's not what should be accessible from python plugins. At least there're no other reasons for it, and for current case registering usermessage hook is better. Espsecially since there're plans for built-in support for it.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Postby decompile » Tue Mar 29, 2016 4:15 pm

satoon101 wrote:The cleanest way would be to hook SayText2, get the msg_name, and override it if the message is a normal chat message. That would also help to keep the same RecipientFilter on say_team as well as dead/spec player chat.


Im not realy understanding the way how to override it, the example in the link shows how to get it but afterwards to block the old msg and send the new (or however that works)
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Tue Mar 29, 2016 4:26 pm

No, I assume the example in the links shows how to get ProtobufMessage object of the sent message, then you can alter it, for example,

Syntax: Select all

buffer.set_string('msg_name', "My message")

However, I'm not sure if that works if the game uses bitbuf messages
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Tue Mar 29, 2016 4:55 pm

iPlayer wrote:No, I assume the example in the links shows how to get ProtobufMessage object of the sent message, then you can alter it, for example,
[PYTHON]buffer.set_string('msg_name', "My message")[/PYTHON]

Exactly! Though, I should mention that the code in the other thread isn't working anymore, because I have changed the internal structure some months ago. But getting a ProtobufMessage is now much easier. You just need to use memory.make_object(ProtobufMessage, args[3]). I can update the code if anyone needs it.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Postby decompile » Thu Mar 31, 2016 11:00 pm

Can someone post a snippet and comment it? Hard to understand for me
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Postby decompile » Tue Apr 05, 2016 11:22 pm

Wouldn't it be possible to make a check before the CommandReturn.BLOCK, if its a command it gets fired (as usual) but still get blocked, thats how I Thought it could be possible
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Wed Apr 06, 2016 5:06 am

That's basically what I proposed, but it won't work with SM commands. No, hooking is surely better.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Wed Apr 06, 2016 7:53 pm

decompile, try this (props to Ayuto for original code)

Syntax: Select all

from commands.say import SayCommand
from memory import Convention, DataType, get_object_pointer, make_object
from memory.hooks import PreHook
from messages import SayText2
from engines.server import engine_server
from messages import UserMessage
from _messages import ProtobufMessage


saytext2_index = UserMessage(RecipientFilter(), 'SayText2').message_index

# virtual void SendUserMessage( IRecipientFilter &filter, int message, const google::protobuf::Message &msg ) = 0;
send_user_message = get_object_pointer(engine_server).make_virtual_function(
45,
Convention.THISCALL,
[DataType.POINTER, DataType.POINTER, DataType.INT, DataType.POINTER],
DataType.VOID
)


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

buffer = make_object(ProtobufMessage, args[3])

player_name = buffer.get_repeated_string('params', 0)
message = buffer.get_repeated_string('params', 1)
buffer.set_string('msg_name', "\x02{} \x01says: \x10{}".format(player_name, message))


@SayCommand("!test")
def say_test(command, index, team_only):
print("Issued !test by (index={})".format(index))


Everything works. Note how I used params to get the initial name and message and then msg_name to create a new one. Initial msg_name only contains string like Cstrike_Chat_AllDead
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Wed Apr 06, 2016 8:25 pm

Correct me if I am wrong, but I am fairly certain you can still use the original msg_name and just modify the first parameter. This will help to keep the full original message intact, including the *DEAD* and *SPEC* tags, which will still be shown in the clients language.

*Edit: same goes for the player's team and location in team chat messages.
Image
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Wed Apr 06, 2016 8:27 pm

Yeah, I thought of it, but what if you want, you know, change the formatting? Like in my example, it shows something like
iPlayer says !test

While the game would have printed
iPlayer: !test


The good thing is that SayCommand still fires when the whole message is included in msg_name.

EDIT: What is more, when inserted in, say, params #0, colors don't seems to work as they usually do, I only get team color and white.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Postby decompile » Wed Apr 06, 2016 10:35 pm

Is it possible to make it possible that alive players can see dead messages and spectator messages?

EDIT:

Thank you for the start!
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Wed Apr 06, 2016 10:42 pm

Try this

Syntax: Select all

from filters.recipients import RecipientFilter

# ...


@PreHook(send_user_message)
def pre_send_user_message(args):
args[1] = RecipientFilter() # If we don't pass any filters, this RecipientFilter will target all existing players

# ...
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Thu Apr 07, 2016 6:40 am

Better just call make_object(RecipientFilter, args[1]).add_all_players(). But I think there is a ConVar as well. Just can't remember its name.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Postby decompile » Thu Apr 07, 2016 4:33 pm

When im trying to load it, Ill get

Syntax: Select all

from _messages import ProtobufMessage

ImportError: cannot import name 'ProtobufMessage'


Current Source.Python version: 304

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 40 guests