mirror of
https://github.com/p2r3/bareiron.git
synced 2025-10-01 23:25:09 +02:00
implement !msg and !help chat commands
* Added the !msg and !help command * Started fixing issues * Rewrote !msg processing in chat system * cleanup --------- Co-authored-by: p2r3 <p2r3@p2r3.com>
This commit is contained in:
@@ -14,6 +14,7 @@ int getClientIndex (int client_fd);
|
||||
void resetPlayerData (PlayerData *player);
|
||||
int reservePlayerData (int client_fd, uint8_t *uuid, char* name);
|
||||
int getPlayerData (int client_fd, PlayerData **output);
|
||||
PlayerData *getPlayerByName (int start_offset, int end_offset, uint8_t *buffer);
|
||||
void handlePlayerDisconnect (int client_fd);
|
||||
void handlePlayerJoin (PlayerData* player);
|
||||
void disconnectClient (int *client_fd, int cause);
|
||||
|
@@ -1131,29 +1131,95 @@ int cs_chat (int client_fd) {
|
||||
message_len = 224;
|
||||
}
|
||||
|
||||
// Shift message contents forward to make space for player name tag
|
||||
memmove(recv_buffer + name_len + 3, recv_buffer, message_len + 1);
|
||||
// Copy player name to index 1
|
||||
memcpy(recv_buffer + 1, player->name, name_len);
|
||||
// Surround player name with brackets and a space
|
||||
recv_buffer[0] = '<';
|
||||
recv_buffer[name_len + 1] = '>';
|
||||
recv_buffer[name_len + 2] = ' ';
|
||||
if (recv_buffer[0] != '!') { // Standard chat message
|
||||
|
||||
// Forward message to all connected players
|
||||
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
||||
if (player_data[i].client_fd == -1) continue;
|
||||
if (player_data[i].flags & 0x20) continue;
|
||||
sc_systemChat(player_data[i].client_fd, (char *)recv_buffer, message_len + name_len + 3);
|
||||
// Shift message contents forward to make space for player name tag
|
||||
memmove(recv_buffer + name_len + 3, recv_buffer, message_len + 1);
|
||||
// Copy player name to index 1
|
||||
memcpy(recv_buffer + 1, player->name, name_len);
|
||||
// Surround player name with brackets and a space
|
||||
recv_buffer[0] = '<';
|
||||
recv_buffer[name_len + 1] = '>';
|
||||
recv_buffer[name_len + 2] = ' ';
|
||||
|
||||
// Forward message to all connected players
|
||||
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
||||
if (player_data[i].client_fd == -1) continue;
|
||||
if (player_data[i].flags & 0x20) continue;
|
||||
sc_systemChat(player_data[i].client_fd, (char *)recv_buffer, message_len + name_len + 3);
|
||||
}
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Handle chat commands
|
||||
|
||||
if (!strncmp(recv_buffer, "!msg", 4)) {
|
||||
|
||||
int target_offset = 5;
|
||||
int target_end_offset = 0;
|
||||
int text_offset = 0;
|
||||
|
||||
// Skip spaces after "!msg"
|
||||
while (recv_buffer[target_offset] == ' ') target_offset++;
|
||||
target_end_offset = target_offset;
|
||||
// Extract target name
|
||||
while (recv_buffer[target_end_offset] != ' ' && recv_buffer[target_end_offset] != '\0' && target_end_offset < 21) target_end_offset++;
|
||||
text_offset = target_end_offset;
|
||||
// Skip spaces before message
|
||||
while (recv_buffer[text_offset] == ' ') text_offset++;
|
||||
|
||||
// Send usage guide if arguments are missing
|
||||
if (target_offset == target_end_offset || target_end_offset == text_offset) {
|
||||
sc_systemChat(client_fd, "§7Usage: !msg <player> <message>", 33);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Query the target player
|
||||
PlayerData *target = getPlayerByName(target_offset, target_end_offset, recv_buffer);
|
||||
if (target == NULL) {
|
||||
sc_systemChat(client_fd, "Player not found", 16);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Format output as a vanilla whisper
|
||||
int name_len = strlen(player->name);
|
||||
int text_len = message_len - text_offset;
|
||||
memmove(recv_buffer + name_len + 24, recv_buffer + text_offset, text_len);
|
||||
snprintf(recv_buffer, sizeof(recv_buffer), "§7§o%s whispers to you:", player->name);
|
||||
recv_buffer[name_len + 23] = ' ';
|
||||
// Send message to target player
|
||||
sc_systemChat(target->client_fd, (char *)recv_buffer, (uint16_t)(name_len + 24 + text_len));
|
||||
|
||||
// Format output for sending player
|
||||
int target_len = target_end_offset - target_offset;
|
||||
memmove(recv_buffer + target_len + 23, recv_buffer + name_len + 24, text_len);
|
||||
snprintf(recv_buffer, sizeof(recv_buffer), "§7§oYou whisper to %s:", target->name);
|
||||
recv_buffer[target_len + 22] = ' ';
|
||||
// Report back to sending player
|
||||
sc_systemChat(client_fd, (char *)recv_buffer, (uint16_t)(target_len + 23 + text_len));
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!strncmp(recv_buffer, "!help", 5)) {
|
||||
// Send command guide
|
||||
const char help_msg[] = "§7Commands:\n"
|
||||
" !msg <player> <message> - Send a private message\n"
|
||||
" !help - Show this help message";
|
||||
sc_systemChat(client_fd, (char *)help_msg, (uint16_t)sizeof(help_msg) - 1);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Handle fall-through case
|
||||
sc_systemChat(client_fd, "§7Unknown command", 18);
|
||||
|
||||
cleanup:
|
||||
readUint64(client_fd); // Ignore timestamp
|
||||
readUint64(client_fd); // Ignore salt
|
||||
|
||||
// Ignore signature (if any)
|
||||
uint8_t has_signature = readByte(client_fd);
|
||||
if (has_signature) recv_all(client_fd, recv_buffer, 256, false);
|
||||
|
||||
readVarInt(client_fd); // Ignore message count
|
||||
// Ignore acknowledgement bitmask and checksum
|
||||
recv_all(client_fd, recv_buffer, 4, false);
|
||||
|
@@ -125,6 +125,22 @@ int getPlayerData (int client_fd, PlayerData **output) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns the player with the given name, or NULL if not found
|
||||
PlayerData *getPlayerByName (int start_offset, int end_offset, uint8_t *buffer) {
|
||||
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
||||
if (player_data[i].client_fd == -1) continue;
|
||||
int j;
|
||||
for (j = start_offset; j < end_offset && j < 256 && buffer[j] != ' '; j++) {
|
||||
if (player_data[i].name[j - start_offset] != buffer[j]) break;
|
||||
}
|
||||
if ((j == end_offset || buffer[j] == ' ') && j < 256) {
|
||||
return &player_data[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Marks a client as disconnected and cleans up player data
|
||||
void handlePlayerDisconnect (int client_fd) {
|
||||
// Search for a corresponding player in the player data array
|
||||
|
Reference in New Issue
Block a user