commit - ba86dfd927b5e2432be797e12095642dc4091fe1
commit + b23e19ecd4f7a33e6cd03ab53103b65ccf4f8f1d
blob - f3aa33133e0b13d3946824c2a4ebe4271a82ca63
blob + b7273c8c7da9c4d5ec7c63ddb234af001c60147d
--- include/procedures.h
+++ include/procedures.h
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);
blob - 5cec9d5f195917440195a5cd8a89e4ab4da15f79
blob + cbb110903212a3c5afd085aa3c8cdc688d50d4cc
--- src/packets.c
+++ src/packets.c
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);
blob - 4048bba6d0431bab6dc4aa1f20f317ff3e957ab6
blob + 7bc5d9d1280909b40a64044118715539d0e40972
--- src/procedures.c
+++ src/procedures.c
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