Modifying chat with sayfilter but SayCommand doesnt "register"

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
iPlayer
Developer
Posts: 493
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby iPlayer » Thu Jun 23, 2016 4:14 pm

This is the line where RecipientFilter is set. Note USERMSG_BLOCKHOOKS flag. Does it have anything to do with the issue?
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby L'In20Cible » Thu Jun 23, 2016 5:33 pm

For future reference, Using the following code fixed his issue:

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Source.Python
from engines.server import engine_server
from filters.recipients import RecipientFilter

from bitbuffers import BitBufferWrite
from bitbuffers import BitBufferRead

import memory

from memory import Convention
from memory import DataType
from memory.hooks import PreHook
from memory.hooks import PostHook


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
engine_server_ptr = memory.get_object_pointer(engine_server)

# CVEngineServer::UserMessageBegin(IRecipientFilter *, int)
UserMessageBegin = engine_server_ptr.make_virtual_function(
43,
Convention.THISCALL,
[DataType.POINTER, DataType.POINTER, DataType.INT],
DataType.POINTER
)

# CVEngineServer::MessageEnd(void)
MessageEnd = engine_server_ptr.make_virtual_function(
44,
Convention.THISCALL,
[DataType.POINTER],
DataType.VOID
)

user_message_data = None


# =============================================================================
# >> HOOKS
# =============================================================================
@PostHook(UserMessageBegin)
def post_user_message_begin(args, return_value):
global user_message_data
user_message_data = (args[2],
memory.make_object(BitBufferWrite, return_value))

@PreHook(MessageEnd)
def pre_message_end(args):
# This happens when we initialize our hooks, while a user message is
# currently being created
if user_message_data is None:
return

message_index, buffer = user_message_data
on_user_message_created(message_index, BitBufferRead(buffer), buffer)


# =============================================================================
# >> TEST
# =============================================================================
from messages import get_message_index

saytext2_index = get_message_index('SayText2')

def on_user_message_created(message_index, buffer_read, buffer_write):
if message_index != saytext2_index:
return

index = buffer_read.read_byte()
chat = buffer_read.read_byte()
message = buffer_read.read_string()
param1 = buffer_read.read_string()

param2_bits = buffer_read.num_bits_read
param2 = buffer_read.read_string()

param3 = buffer_read.read_string()
param4 = buffer_read.read_string()

print(index, chat, message, param1, param2, param3, param4)

# Seek to the param2 bit. At that bit the actual message is stored, which
# we want to modify.
buffer_write.seek_to_bit(param2_bits)

new_message = 'Hello world!'
buffer_write.write_string(new_message)

if len(new_message) != len(param2):
# We need to rewrite the buffer, because the user message might be
# corrupt now :(
buffer_write.write_string(param3)
buffer_write.write_string(param4)


The hook was raising when the message was initialized by SM (CRecipientFilter wrapper class compiled with no-rtti).
User avatar
iPlayer
Developer
Posts: 493
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby iPlayer » Thu Jun 23, 2016 8:22 pm

As I see it, param2 doesn't support color tags. Like, at all. So you'll have to put your actual message into message name (instead of default Cstrike_Chat_All or something) if you want colors.

Syntax: Select all

index = buffer_read.read_byte()
chat = buffer_read.read_byte()

message_bits = buffer_read.num_bits_read
message = buffer_read.read_string()

param1 = buffer_read.read_string()
param2 = buffer_read.read_string()

new_message = "\x01{}[ADMIN] {}: {}{}".format(Color(255, 0, 0), param1, Color(255, 255, 255), param2)

buffer_write.seek_to_bit(message_bits)
buffer_write.write_string(new_message)

buffer_write.write_string("")
buffer_write.write_string("")
buffer_write.write_string("")
buffer_write.write_string("")

(full code: http://pastebin.com/RTuiZ3fv)
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots

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

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Thu Jun 23, 2016 9:14 pm

Don't we need to filter the way, currently its replacing every message send to the player. Like a small check that it comes from a player the message.
decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Mon Jul 04, 2016 12:29 pm

How do you filter out the normal messages so it only modifies the playermessages?
User avatar
iPlayer
Developer
Posts: 493
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby iPlayer » Tue Jul 05, 2016 5:38 am

Yeah, do a bit of testing and see what original message contains. It can contain such stuff as "Cstrike_Chat_All" or something.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots

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

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Sat Jul 23, 2016 11:56 am

So after using thise quite few hours, I needed to disable it cause it caused server crashes. I can't tell much since there are no errors or anything, but it crashes "randomly" after someone types in chat.

(I wasn't using the on_user_message_created part)

EDIT:

After trying to find some stuff about that on sourcemod, I found a pretty nice plugin which most people use for modifying chat messages like giving their players colored names etc.

Its called Simple Chat Processor

https://bitbucket.org/minimoney1/simple ... cessor/src

Maybe this coulda help?
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby L'In20Cible » Sun Jul 24, 2016 9:09 pm

decompile wrote:So after using thise quite few hours, I needed to disable it cause it caused server crashes. I can't tell much since there are no errors or anything, but it crashes "randomly" after someone types in chat.
I don't believe it to crash randomly, to be honnest. I would rather bet on another plugin doing other stuff at the same time which corrupt the passed data or something. Does it crash when a registered say command (either by SM or SP) is used, for example?

decompile wrote:(I wasn't using the on_user_message_created part)
What code are you currently using? Always a better idea to post/link actual code when a lot of different ones has been posted.
decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Sun Jul 24, 2016 10:33 pm

I'm sorry.

I was using this code

decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Wed Jan 18, 2017 5:15 pm

Mhm, I guess it would be good to have an updated and maybe even better code like a package to modify chat messages or else.

Im currenlty using a method with SayFilter where im getting the chat message/player informations, and just block it and sending a SayText2 with the informations, in colors.

It works, but it doesnt collaborate with other plugins such as GAG from sourcemod, or other plugins which use chat messages as informations for their plugin.
User avatar
Kami
Global Moderator
Posts: 81
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby Kami » Wed Jan 18, 2017 6:51 pm

I had the same problem with other plugin say command compatibility when making a sayfilter with sourcemod and I bypassed this by making a "whitelist" that includes all commands (yes you'd have to do this by hand propably) and then just check in the sayhook if the command is in the whitelist and then execute it in client console (at least if it is sourcemod the say commands will have a client console variant too)
decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Wed Jan 18, 2017 7:05 pm

Oh ye, good idea but Im still more for the way of changing the actual message instead of blocking it.

Sourcemod uses this method with a nice "api/package".

https://forums.alliedmods.net/showthread.php?t=286913

A plugin with available API to hook and change clients name and message strings.

I wish I could start wit hthat, but I have absolutely no clue how protobuf or anything else works. :(
User avatar
Kill
Member
Posts: 73
Joined: Wed Aug 31, 2016 10:05 pm

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby Kill » Thu Jan 19, 2017 6:33 pm

decompile wrote:Oh ye, good idea but Im still more for the way of changing the actual message instead of blocking it.

Sourcemod uses this method with a nice "api/package".

https://forums.alliedmods.net/showthread.php?t=286913

A plugin with available API to hook and change clients name and message strings.

I wish I could start wit hthat, but I have absolutely no clue how protobuf or anything else works. :(


It would be awesome if someone could make a tutorial on that!
User avatar
Ayuto
Project Leader
Posts: 1578
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby Ayuto » Sat Jan 21, 2017 3:50 pm

decompile wrote:I wish I could start wit hthat, but I have absolutely no clue how protobuf or anything else works. :(

Well, it's quite simple. Just reverse this code:
https://github.com/Source-Python-Dev-Te ... #L255-L274

Example:

Syntax: Select all

def on_user_message_created(recipients, message_index, buffer_read, buffer_write):
if message_index != saytext2_index:
return

# Retrieve SayText2 parameters
index = buffer_read.read_byte()
chat = buffer_read.read_byte()
message = buffer_read.read_string()
param1 = buffer_read.read_string()
param2 = buffer_read.read_string()
param3 = buffer_read.read_string()
param4 = buffer_read.read_string()

# Do you modification here...
param2 = 'Blabla'

# Set SayText2 parameters
buffer_write.seek_to_bit(0)
buffer_write.write_byte(index)
buffer_write.write_byte(chat)
buffer_write.write_string(message)
buffer_write.write_string(param1)
buffer_write.write_string(param2)
buffer_write.write_string(param3)
buffer_write.write_string(param4)


For Protobuf it would look like this:

Syntax: Select all

# Retrieve SayText2 parameters
index = buffer.get_int32('ent_idx')
chat = buffer.get_bool('chat')
message = buffer.get_string('msg_name')
param1 = buffer.get_repeated_string('params', 0)
param2 = buffer.get_repeated_string('params', 1)
param3 = buffer.get_repeated_string('params', 2)
param4 = buffer.get_repeated_string('params', 3)

# Do you modification here...
param2 = 'Blabla'

# Set SayText2 parameters
buffer.set_string('msg_name', message)
buffer.set_bool('chat', chat)
buffer.set_int32('ent_idx', index)
buffer.add_string('params', param1)
buffer.add_string('params', param2)
buffer.add_string('params', param3)
buffer.add_string('params', param4)
For bitbuffers the order is absolutely important. With Protobuf it doesn't matter unless you are adding repeated attributes.
decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Sun Jan 22, 2017 12:47 am

Alright, I tried to play with it abit.

Im currently testing out CS:S windows.
And it works so far, but the only problem is:

Is there a way to modify the Recipients filter for the message, since I want to make the message viewable for everyone, some sort of Dead-Chat.

iPlayer made a plugin which modified that with a saytext2 filter, wondering if I can do it directly in the message, since ayuto used Recipients as an arg in the first post.
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby L'In20Cible » Sun Jan 22, 2017 1:11 am

Once you have wrapped the filter, you can add/remove recipients.

Syntax: Select all

recipients.add_all_players()
However, you won't be able to wrap the filter if the message has been initialized by SM. Main reason being that their class is compiled with no RTTI data that Boost rely on and the fact that while we use the same structure as the engine, they use a different one so accessing/modifying it will have undefined behaviours (even if you copy it while we suggested here; structures still differs).
decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Sun Jan 22, 2017 11:07 pm

Hey!

Thank you.
I remember iPlayer tried adding a DeadChat, but I can remember why I removed it now.

Syntax: Select all

@PreHook(saytext2_filter)
def pre_saytext2_filter(args):
recipient_filter = make_object(RecipientFilter, args[0])
msg_name = args[3]

if msg_name in ("Cstrike_Chat_AllDead", "Cstrike_Chat_AllSpec"):
recipient_filter.add_all_players()

elif msg_name == "Cstrike_Chat_T_Dead":
recipient_filter.update(PlayerIter('t'))

elif msg_name == "Cstrike_Chat_CT_Dead":
recipient_filter.update(PlayerIter('ct'))


When using this, I noticed that say_team messages which are dead, are getting printed multiple times. Lets say when I write "say_team yo whaddup", it prints me 2x "yo waddup". I dont know if it happens, if more people are in the team, but I think it should work like that
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby L'In20Cible » Sun Jan 22, 2017 11:23 pm

What is your complete code?
decompile
Senior Member
Posts: 287
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby decompile » Sun Jan 22, 2017 11:26 pm

L'In20Cible wrote:What is your complete code?


https://github.com/KirillMysnik/sp-dead ... hat_css.py
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Modifying chat with sayfilter but SayCommand doesnt "register"

Postby L'In20Cible » Sun Jan 22, 2017 11:39 pm

Actually, since the RecipientFilter class doesn't have an _obj method, the instance returned by make_object is of type _RecipientFilter (its base class) which doesn't have any update method exposed. This is definitely something we need to improve on our end. If I do fix the code:

Syntax: Select all

@PreHook(saytext2_filter)
def pre_saytext2_filter(args):
recipient_filter = make_object(RecipientFilter, args[0])
msg_name = args[3]

if msg_name in ("Cstrike_Chat_AllDead", "Cstrike_Chat_AllSpec"):
recipient_filter.add_all_players()

else:
players = None
if msg_name == "Cstrike_Chat_T_Dead":
players = PlayerIter('t')
elif msg_name == "Cstrike_Chat_CT_Dead":
players = PlayerIter('t')
if players is not None:
for player in players:
recipient_filter.add_recipient(player.index)
It works, and I'm not getting the message twice. Are you using any plugins that hook/filter/modify the chat messages?

Return to “Plugin Development Support”

Who is online

Users browsing this forum: Baidu [Spider] and 1 guest