@@ -1131,29 +1131,95 @@ int cs_chat (int client_fd) {
11311131 message_len = 224 ;
11321132 }
11331133
1134- // Shift message contents forward to make space for player name tag
1135- memmove (recv_buffer + name_len + 3 , recv_buffer , message_len + 1 );
1136- // Copy player name to index 1
1137- memcpy (recv_buffer + 1 , player -> name , name_len );
1138- // Surround player name with brackets and a space
1139- recv_buffer [0 ] = '<' ;
1140- recv_buffer [name_len + 1 ] = '>' ;
1141- recv_buffer [name_len + 2 ] = ' ' ;
1142-
1143- // Forward message to all connected players
1144- for (int i = 0 ; i < MAX_PLAYERS ; i ++ ) {
1145- if (player_data [i ].client_fd == -1 ) continue ;
1146- if (player_data [i ].flags & 0x20 ) continue ;
1147- sc_systemChat (player_data [i ].client_fd , (char * )recv_buffer , message_len + name_len + 3 );
1134+ if (recv_buffer [0 ] != '!' ) { // Standard chat message
1135+
1136+ // Shift message contents forward to make space for player name tag
1137+ memmove (recv_buffer + name_len + 3 , recv_buffer , message_len + 1 );
1138+ // Copy player name to index 1
1139+ memcpy (recv_buffer + 1 , player -> name , name_len );
1140+ // Surround player name with brackets and a space
1141+ recv_buffer [0 ] = '<' ;
1142+ recv_buffer [name_len + 1 ] = '>' ;
1143+ recv_buffer [name_len + 2 ] = ' ' ;
1144+
1145+ // Forward message to all connected players
1146+ for (int i = 0 ; i < MAX_PLAYERS ; i ++ ) {
1147+ if (player_data [i ].client_fd == -1 ) continue ;
1148+ if (player_data [i ].flags & 0x20 ) continue ;
1149+ sc_systemChat (player_data [i ].client_fd , (char * )recv_buffer , message_len + name_len + 3 );
1150+ }
1151+
1152+ goto cleanup ;
1153+ }
1154+
1155+ // Handle chat commands
1156+
1157+ if (!strncmp (recv_buffer , "!msg" , 4 )) {
1158+
1159+ int target_offset = 5 ;
1160+ int target_end_offset = 0 ;
1161+ int text_offset = 0 ;
1162+
1163+ // Skip spaces after "!msg"
1164+ while (recv_buffer [target_offset ] == ' ' ) target_offset ++ ;
1165+ target_end_offset = target_offset ;
1166+ // Extract target name
1167+ while (recv_buffer [target_end_offset ] != ' ' && recv_buffer [target_end_offset ] != '\0' && target_end_offset < 21 ) target_end_offset ++ ;
1168+ text_offset = target_end_offset ;
1169+ // Skip spaces before message
1170+ while (recv_buffer [text_offset ] == ' ' ) text_offset ++ ;
1171+
1172+ // Send usage guide if arguments are missing
1173+ if (target_offset == target_end_offset || target_end_offset == text_offset ) {
1174+ sc_systemChat (client_fd , "§7Usage: !msg <player> <message>" , 33 );
1175+ goto cleanup ;
1176+ }
1177+
1178+ // Query the target player
1179+ PlayerData * target = getPlayerByName (target_offset , target_end_offset , recv_buffer );
1180+ if (target == NULL ) {
1181+ sc_systemChat (client_fd , "Player not found" , 16 );
1182+ goto cleanup ;
1183+ }
1184+
1185+ // Format output as a vanilla whisper
1186+ int name_len = strlen (player -> name );
1187+ int text_len = message_len - text_offset ;
1188+ memmove (recv_buffer + name_len + 24 , recv_buffer + text_offset , text_len );
1189+ snprintf (recv_buffer , sizeof (recv_buffer ), "§7§o%s whispers to you:" , player -> name );
1190+ recv_buffer [name_len + 23 ] = ' ' ;
1191+ // Send message to target player
1192+ sc_systemChat (target -> client_fd , (char * )recv_buffer , (uint16_t )(name_len + 24 + text_len ));
1193+
1194+ // Format output for sending player
1195+ int target_len = target_end_offset - target_offset ;
1196+ memmove (recv_buffer + target_len + 23 , recv_buffer + name_len + 24 , text_len );
1197+ snprintf (recv_buffer , sizeof (recv_buffer ), "§7§oYou whisper to %s:" , target -> name );
1198+ recv_buffer [target_len + 22 ] = ' ' ;
1199+ // Report back to sending player
1200+ sc_systemChat (client_fd , (char * )recv_buffer , (uint16_t )(target_len + 23 + text_len ));
1201+
1202+ goto cleanup ;
11481203 }
11491204
1205+ if (!strncmp (recv_buffer , "!help" , 5 )) {
1206+ // Send command guide
1207+ const char help_msg [] = "§7Commands:\n"
1208+ " !msg <player> <message> - Send a private message\n"
1209+ " !help - Show this help message" ;
1210+ sc_systemChat (client_fd , (char * )help_msg , (uint16_t )sizeof (help_msg ) - 1 );
1211+ goto cleanup ;
1212+ }
1213+
1214+ // Handle fall-through case
1215+ sc_systemChat (client_fd , "§7Unknown command" , 18 );
1216+
1217+ cleanup :
11501218 readUint64 (client_fd ); // Ignore timestamp
11511219 readUint64 (client_fd ); // Ignore salt
1152-
11531220 // Ignore signature (if any)
11541221 uint8_t has_signature = readByte (client_fd );
11551222 if (has_signature ) recv_all (client_fd , recv_buffer , 256 , false);
1156-
11571223 readVarInt (client_fd ); // Ignore message count
11581224 // Ignore acknowledgement bitmask and checksum
11591225 recv_all (client_fd , recv_buffer , 4 , false);
0 commit comments