mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-05-10 19:00:57 +08:00
feat: add :nick command and /me action messages
- :nick/:name <name>: change username in-session with full validation, thread-safe update under write lock, and system broadcast - /me <action>: IRC-style action messages displayed as "* user action" - Updated help text (EN/ZH) and manpage with new commands Closes #38
This commit is contained in:
parent
450f1828fd
commit
e2990000e6
3 changed files with 53 additions and 2 deletions
|
|
@ -1147,6 +1147,7 @@ static void execute_command(client_t *client) {
|
||||||
" Available Commands\n"
|
" Available Commands\n"
|
||||||
"========================================\n"
|
"========================================\n"
|
||||||
"list, users, who - Show online users\n"
|
"list, users, who - Show online users\n"
|
||||||
|
"nick/name <name> - Change nickname\n"
|
||||||
"msg/w <user> <text> - Whisper to user\n"
|
"msg/w <user> <text> - Whisper to user\n"
|
||||||
"help, commands - Show this help\n"
|
"help, commands - Show this help\n"
|
||||||
"clear, cls - Clear command output\n"
|
"clear, cls - Clear command output\n"
|
||||||
|
|
@ -1201,6 +1202,40 @@ static void execute_command(client_t *client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strncmp(cmd, "nick ", 5) == 0 || strncmp(cmd, "name ", 5) == 0) {
|
||||||
|
char *new_name = cmd + 5;
|
||||||
|
while (*new_name == ' ') new_name++;
|
||||||
|
|
||||||
|
if (new_name[0] == '\0') {
|
||||||
|
buffer_appendf(output, sizeof(output), &pos,
|
||||||
|
"Usage: nick <new_username>\n");
|
||||||
|
} else if (!is_valid_username(new_name)) {
|
||||||
|
buffer_appendf(output, sizeof(output), &pos,
|
||||||
|
"Invalid username\n");
|
||||||
|
} else {
|
||||||
|
char validated_name[MAX_USERNAME_LEN];
|
||||||
|
snprintf(validated_name, sizeof(validated_name), "%s", new_name);
|
||||||
|
if (utf8_strlen(validated_name) > 20) {
|
||||||
|
utf8_truncate(validated_name, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
char old_name[MAX_USERNAME_LEN];
|
||||||
|
pthread_rwlock_wrlock(&g_room->lock);
|
||||||
|
snprintf(old_name, sizeof(old_name), "%s", client->username);
|
||||||
|
snprintf(client->username, MAX_USERNAME_LEN, "%s", validated_name);
|
||||||
|
pthread_rwlock_unlock(&g_room->lock);
|
||||||
|
|
||||||
|
message_t nick_msg = { .timestamp = time(NULL) };
|
||||||
|
snprintf(nick_msg.username, MAX_USERNAME_LEN, "系统");
|
||||||
|
snprintf(nick_msg.content, MAX_MESSAGE_LEN,
|
||||||
|
"%s 更名为 %s", old_name, client->username);
|
||||||
|
room_broadcast(g_room, &nick_msg);
|
||||||
|
message_save(&nick_msg);
|
||||||
|
|
||||||
|
buffer_appendf(output, sizeof(output), &pos,
|
||||||
|
"Nickname changed: %s -> %s\n", old_name, client->username);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0 ||
|
} else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0 ||
|
||||||
strcmp(cmd, "exit") == 0) {
|
strcmp(cmd, "exit") == 0) {
|
||||||
client->connected = false;
|
client->connected = false;
|
||||||
|
|
@ -1296,8 +1331,18 @@ static bool handle_key(client_t *client, unsigned char key, char *input) {
|
||||||
message_t msg = {
|
message_t msg = {
|
||||||
.timestamp = time(NULL),
|
.timestamp = time(NULL),
|
||||||
};
|
};
|
||||||
snprintf(msg.username, sizeof(msg.username), "%s", client->username);
|
if (strncmp(input, "/me ", 4) == 0 && input[4] != '\0') {
|
||||||
snprintf(msg.content, sizeof(msg.content), "%s", input);
|
msg.username[0] = '*';
|
||||||
|
msg.username[1] = '\0';
|
||||||
|
int n = snprintf(msg.content, sizeof(msg.content), "%s %s",
|
||||||
|
client->username, input + 4);
|
||||||
|
if (n >= (int)sizeof(msg.content)) {
|
||||||
|
msg.content[sizeof(msg.content) - 1] = '\0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(msg.username, sizeof(msg.username), "%s", client->username);
|
||||||
|
snprintf(msg.content, sizeof(msg.content), "%s", input);
|
||||||
|
}
|
||||||
room_broadcast(g_room, &msg);
|
room_broadcast(g_room, &msg);
|
||||||
message_save(&msg);
|
message_save(&msg);
|
||||||
input[0] = '\0';
|
input[0] = '\0';
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,8 @@ const char* tui_get_help_text(help_lang_t lang) {
|
||||||
"\n"
|
"\n"
|
||||||
"AVAILABLE COMMANDS:\n"
|
"AVAILABLE COMMANDS:\n"
|
||||||
" list, users, who - Show online users\n"
|
" list, users, who - Show online users\n"
|
||||||
|
" nick/name <name> - Change nickname\n"
|
||||||
|
" msg/w <user> <text> - Whisper to user\n"
|
||||||
" help, commands - Show available commands\n"
|
" help, commands - Show available commands\n"
|
||||||
" clear, cls - Clear command output\n"
|
" clear, cls - Clear command output\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -347,6 +349,8 @@ const char* tui_get_help_text(help_lang_t lang) {
|
||||||
"\n"
|
"\n"
|
||||||
"可用命令:\n"
|
"可用命令:\n"
|
||||||
" list, users, who - 显示在线用户\n"
|
" list, users, who - 显示在线用户\n"
|
||||||
|
" nick/name <名字> - 更改昵称\n"
|
||||||
|
" msg/w <用户> <文本> - 私聊\n"
|
||||||
" help, commands - 显示可用命令\n"
|
" help, commands - 显示可用命令\n"
|
||||||
" clear, cls - 清空命令输出\n"
|
" clear, cls - 清空命令输出\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
2
tnt.1
2
tnt.1
|
|
@ -97,6 +97,8 @@ Ctrl+C Disconnect
|
||||||
.TS
|
.TS
|
||||||
l l.
|
l l.
|
||||||
:list Show online users
|
:list Show online users
|
||||||
|
:nick \fIname\fR Change nickname
|
||||||
|
:name \fIname\fR Alias for :nick
|
||||||
:msg \fIuser text\fR Send private whisper
|
:msg \fIuser text\fR Send private whisper
|
||||||
:w \fIuser text\fR Short alias for :msg
|
:w \fIuser text\fR Short alias for :msg
|
||||||
:help Show available commands
|
:help Show available commands
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue