2424#pragma semicolon 1
2525#pragma newdecls required
2626
27- #define PLUGIN_VERSION " 22w26b "
27+ #define PLUGIN_VERSION " 22w26c "
2828
2929public Plugin myinfo = {
3030 name = " Meta Chat Processor" ,
@@ -166,8 +166,10 @@ public void OnPluginStart() {
166166
167167 UserMsg userMessage ;
168168 if ((userMessage = GetUserMessageId (" SayText2" )) != INVALID_MESSAGE_ID ) {
169- if (g_bUseProtobuf ) HookUserMessage (userMessage , OnUserMessage_SayText2Proto , true );
170- else HookUserMessage (userMessage , OnUserMessage_SayText2BB , true );
169+ if (g_bUseProtobuf )
170+ HookUserMessage (userMessage , OnUserMessage_SayText2Proto , true );
171+ else
172+ HookUserMessage (userMessage , OnUserMessage_SayText2BB , true );
171173 //} else if ((userMessage = GetUserMessageId("SayText")) != INVALID_MESSAGE_ID) {
172174 //SCP only supported dods? maybe add that if people ask for it
173175 } else {
@@ -221,6 +223,7 @@ public Action OnUserMessage_SayText2Proto(UserMsg msg_id, BfRead msg, const int[
221223 // copy as initial display name
222224 strcopy (g_currentMessage .sender_display , sizeof (MessageData ::sender_display ), g_currentMessage .sender_name );
223225
226+ g_currentMessage .listRecipients .Clear ();
224227 for (int reci = 0 ;reci < playersNum ;reci ++ ) {
225228 g_currentMessage .listRecipients .Push (players [reci ]);
226229 }
@@ -247,6 +250,7 @@ public Action OnUserMessage_SayText2BB(UserMsg msg_id, BfRead msg, const int[] p
247250 // copy as initial display name
248251 strcopy (g_currentMessage .sender_display , sizeof (MessageData ::sender_display ), g_currentMessage .sender_name );
249252
253+ g_currentMessage .listRecipients .Clear ();
250254 for (int reci = 0 ;reci < playersNum ;reci ++ ) {
251255 g_currentMessage .listRecipients .Push (players [reci ]);
252256 }
@@ -258,7 +262,7 @@ public Action OnUserMessage_SayText2BB(UserMsg msg_id, BfRead msg, const int[] p
258262Action ProcessSayText2 () {
259263 Action result ;
260264 g_currentMessage .valid = true ;
261- #define THEN_CANCEL { g_currentMessage .valid = true ; return Plugin_Handled ; }
265+ #define THEN_CANCEL { g_currentMessage .valid = false ; return Plugin_Handled ; }
262266
263267 //this is some basic chat sanitizing. should we do this as chat processor?
264268 // i think most server operators wont event know this can be an issue, and
@@ -282,7 +286,8 @@ Action ProcessSayText2() {
282286 BanClient (g_currentMessage .sender , 0 , BANFLAG_AUTHID | BANFLAG_AUTO , " Hacked Client: Invalid characters in chat input (line breaks)" , " Hacked client detected" , " say" , g_currentMessage .sender );
283287 return Plugin_Handled ;
284288 }
285- if (TrimStringMB (tmp ) && tmp [0 ]== 0 ) THEN_CANCEL //message is empty or a "break chat" message
289+ TrimStringMB (tmp );
290+ if (tmp [0 ]== 0 ) THEN_CANCEL //message is empty or a "break chat" message
286291 if (g_sanitizeInput & mcpInputTrimMBSpace ) strcopy (g_currentMessage .message , sizeof (MessageData ::message ), tmp );
287292 }
288293
@@ -312,31 +317,49 @@ Action ProcessSayText2() {
312317
313318 result = g_currentMessage .changed ? Plugin_Handled : Plugin_Continue ;
314319 //send of to next frame as we can't create another user message within this hook
315- g_processedMessages .PushArray (g_currentMessage );
316- g_currentMessage .Reset (.newRecipientsInstace = true ); //because we pushed the list handle, sets valid false
320+ for (int rec = g_currentMessage .listRecipients .Length - 1 ;rec >= 0 ;rec -- ) {
321+ //map client ids to user-ids since we are about to cross tick boundary
322+ int recipient = g_currentMessage .listRecipients .Get (rec );
323+ if (! recipient ) continue ;
324+ g_currentMessage .listRecipients .Set (rec , GetClientUserId ( recipient ));
325+ }
326+ g_processedMessages .PushArray (g_currentMessage ); //push with .valid = true
327+ g_currentMessage .Reset (.newRecipientsInstace = true ); //because we pushed the list handle, sets .valid false
317328
318329#undef THEN_CANCEL
319330 return result ;
320331}
321332//continuation
322333public void OnGameFrame () {
323- for ( int index ; index < g_processedMessages .Length ; index ++ ) {
334+ while ( g_processedMessages .Length > 0 ) {
324335 // pop message
325336 //delete the previous handle, we will fetch an old one from the list
326337 delete g_currentMessage .listRecipients ;
327- g_processedMessages .GetArray (index , g_currentMessage );
328- g_processedMessages .Erase (index );
338+ g_processedMessages .GetArray (0 , g_currentMessage );
339+ g_processedMessages .Erase (0 );
340+ //re-map recipients from uids to clients
341+ for (int i = g_currentMessage .listRecipients .Length - 1 ; i >= 0 ; i -= 1 ) {
342+ int recipient = g_currentMessage .listRecipients .Get (i );
343+ if (! recipient ) continue ; //don't touch server recipient, that's always 0
344+ recipient = GetClientOfUserId (recipient ); // validate
345+ if (recipient ) g_currentMessage .listRecipients .Set (i , recipient );
346+ else g_currentMessage .listRecipients .Erase (i );
347+ }
329348
330349 // process message
331350 //if this failes we hopefully threw an error and will continue processing
332351 //other messages in the next game tick, as this one was already dequeued
333- g_currentMessage .valid = true ;
334- if (g_currentMessage .changed ) ResendChatMessage ();
335- Call_OnChatMessagePost ();
336- g_currentMessage .valid = false ;
352+ if (g_currentMessage .valid ) {
353+ if (g_currentMessage .changed ) ResendChatMessage ();
354+ Call_OnChatMessagePost ();
355+ } else {
356+ LogError (" Pushed or didnt clear invalid message! %N : %s " , g_currentMessage .sender , g_currentMessage .message );
357+ }
337358 }
338359 //we still have an old recipients list here that wasn't deleted. this instance
339360 //will be cleared and reused by the next SayText2 hook
361+ //until then, the message structure is invalid tho
362+ g_currentMessage .valid = false ;
340363}
341364
342365static void ResendChatMessage () {
@@ -350,7 +373,7 @@ static void ResendChatMessage() {
350373 bool chatFlag = ! (g_currentMessage .options & mcpMsgNoConsoleCopy );
351374
352375 int recipientCount = g_currentMessage .listRecipients .Length ;
353- for (int i ; i < recipientCount ; i ++ ) {
376+ for (int i ; i < recipientCount ; i += 1 ) {
354377 int recipient = g_currentMessage .listRecipients .Get (i );
355378 if (! recipient ) continue ;
356379
0 commit comments