Page 2 of 5

Posted: Thu Apr 07, 2016 4:36 pm
by iPlayer
All above code was written for CS:GO. What game do you run?

Posted: Thu Apr 07, 2016 5:02 pm
by decompile
Counter-Strike: Source

Posted: Thu Apr 07, 2016 5:16 pm
by iPlayer
Ok, then it's BitBuf. The code will be different. I'll try to work something out a bit later.

Posted: Thu Apr 07, 2016 9:48 pm
by decompile
iPlayer wrote: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

# ...


Wouldn't this send team messages to all players?

This sourcemod plugin
https://forums.alliedmods.net/showthread.php?t=171734?t=171734

Dead players and spectators can chat with the living players.
Team-only messages remain team-only (if from a dead player, visible to his dead/alive team).
Message formatting and prefixes (Terrorist, Spectator, etc.) completely identical to standard, supporting all client languages.

Posted: Thu Apr 07, 2016 9:57 pm
by iPlayer
Then you don't need need changing msg_name at all. You only need to get it, check it for, say, Cstrike_Chat_AllDead (and other strings) and change recipients filter.
With bitbuf it's a bit different.

I suppose it's worth porting that plugin in a whole so that it supports both CS:S and CS:GO. Again, I'll do it when I'm not busy.

Posted: Thu Apr 07, 2016 11:17 pm
by decompile
Awesome!

Posted: Fri Apr 08, 2016 1:14 am
by iPlayer

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

Posted: Sat Jun 11, 2016 4:52 pm
by decompile
iPlayer wrote: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: :p rotobuf::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))


Is there a CS:S version out of this?

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

Posted: Sat Jun 11, 2016 8:51 pm
by Ayuto
In CS:S (and all the other games that don't use protobuf -- CS:GO is currently the only one that uses protobuf) it requires a little bit more effort and you need to be more careful.

Syntax: Select all

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

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 = (
memory.make_object(BaseRecipientFilter, args[1]),
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

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


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

saytext2_index = get_message_index('SayText2')

def on_user_message_created(
recipients, 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)

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

Posted: Wed Jun 15, 2016 1:08 pm
by decompile
When Im running this, my console gets spammed with:

RuntimeError: Access violation - no RTTI data!

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

Posted: Wed Jun 15, 2016 1:33 pm
by Ayuto
Could you please post the full traceback? Are you testing this with CS:S? Which OS runs on your server?

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

Posted: Wed Jun 15, 2016 1:57 pm
by decompile
CS:S Windows!

Sure, can test linux if needed.

[SP] Caught an Exception:
Traceback (most recent call last):
File '..\addons\source-python\plugins\chatRanks\chatRanks.py', line 286, in post_user_message_begin
memory.make_object(RecipientFilter, args[1]),

RuntimeError: Access violation - no RTTI data!

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

Posted: Wed Jun 15, 2016 3:17 pm
by Ayuto
Well, that is weird... I don't get that error message. It means an invalid, but non-null, IRecipientFilter pointer gets passed to CVEngineServer::UserMessageBegin(IRecipientFilter *, int). Do you have other server plugin installed that might interfere (e.g. SM)?

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

Posted: Wed Jun 15, 2016 4:50 pm
by decompile
Yes, im running SourceMod.

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

Posted: Wed Jun 15, 2016 5:06 pm
by Ayuto
Try disabling it, so we know whether there is a conflict or not.

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

Posted: Wed Jun 15, 2016 9:37 pm
by decompile
When I disable sourcemod, means moving the sourcemod.vdf out of the metamod folder, works fine. No errors.

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

Posted: Wed Jun 22, 2016 3:37 pm
by decompile
Any updates?

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

Posted: Wed Jun 22, 2016 5:16 pm
by iPlayer
Well, while Ayuto doesn't reply, I can suggest you enabling SourceMod, but disabling all its plugins (move all .smx files to 'disabled' folder). And check if our code works fine. If it works, then start enabling SM plugins one by one, checking if everything's stable every time.

That way, if it's not a clash with SM core, we will know which SM plugin interferes.

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

Posted: Wed Jun 22, 2016 6:15 pm
by Ayuto
From what I see in their repo, the hook gets initialized when a plugin calls HookUserMessage.

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

Posted: Thu Jun 23, 2016 3:25 pm
by decompile
EDIT:

So after writing with iPlayer, I figured out I can reproduce the exception. Its CPrintToChat, CPrintToChatAll, dont know if it happens with PrintToChat or PrintToChatAll but it does for the C' ones https://github.com/powerlord/sourcemod- ... rs.inc#L39

2nd Edit: it does with PrintToChat/PrintToChatAll too.