Re: Modifying chat with sayfilter but SayCommand doesnt "register"
Posted: 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?
https://forums.sourcepython.com/
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)
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("")
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: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.
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 wrote:(I wasn't using the on_user_message_created part)
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. :(
decompile wrote:I wish I could start wit hthat, but I have absolutely no clue how protobuf or anything else works. :(
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)
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)
Syntax: Select all
recipients.add_all_players()
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'))
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)