Page 3 of 5

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

Posted: Thu Jun 23, 2016 4:14 pm
by iPlayer
This is the line where RecipientFilter is set. Note USERMSG_BLOCKHOOKS flag. Does it have anything to do with the issue?

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

Posted: Thu Jun 23, 2016 5:33 pm
by L'In20Cible
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).

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

Posted: Thu Jun 23, 2016 8:22 pm
by iPlayer
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)

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

Posted: Thu Jun 23, 2016 9:14 pm
by decompile
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.

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

Posted: Mon Jul 04, 2016 12:29 pm
by decompile
How do you filter out the normal messages so it only modifies the playermessages?

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

Posted: Tue Jul 05, 2016 5:38 am
by iPlayer
Yeah, do a bit of testing and see what original message contains. It can contain such stuff as "Cstrike_Chat_All" or something.

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

Posted: Sat Jul 23, 2016 11:56 am
by decompile
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?

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

Posted: Sun Jul 24, 2016 9:09 pm
by L'In20Cible
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.

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

Posted: Sun Jul 24, 2016 10:33 pm
by decompile
I'm sorry.

I was using this code


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

Posted: Wed Jan 18, 2017 5:15 pm
by decompile
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.

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

Posted: Wed Jan 18, 2017 6:51 pm
by Kami
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)

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

Posted: Wed Jan 18, 2017 7:05 pm
by decompile
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. :(

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

Posted: Thu Jan 19, 2017 6:33 pm
by Kill
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!

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

Posted: Sat Jan 21, 2017 3:50 pm
by Ayuto
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.

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

Posted: Sun Jan 22, 2017 12:47 am
by decompile
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.

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

Posted: Sun Jan 22, 2017 1:11 am
by L'In20Cible
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).

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

Posted: Sun Jan 22, 2017 11:07 pm
by decompile
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

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

Posted: Sun Jan 22, 2017 11:23 pm
by L'In20Cible
What is your complete code?

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

Posted: Sun Jan 22, 2017 11:26 pm
by decompile
L'In20Cible wrote:What is your complete code?


https://github.com/KirillMysnik/sp-dead ... hat_css.py

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

Posted: Sun Jan 22, 2017 11:39 pm
by L'In20Cible
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?