From 5cbaa841d0bf07f75614205059324e5d2adbc5dd Mon Sep 17 00:00:00 2001 From: Joursoir Date: Fri, 27 Nov 2020 01:41:09 +0300 Subject: server: add different messages, support commands('/') and spec-messages --- src/server/rooms.cpp | 205 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 139 insertions(+), 66 deletions(-) (limited to 'src/server/rooms.cpp') diff --git a/src/server/rooms.cpp b/src/server/rooms.cpp index 624eb88..1ffb89a 100644 --- a/src/server/rooms.cpp +++ b/src/server/rooms.cpp @@ -1,23 +1,44 @@ #include #include +#include #include "rooms.hpp" #include "chat.hpp" // hash of commands: -#define CMD_NAME 210647350421 -#define CMD_CREATE 229394553991880 - -const int cmd_num = 2; -const char *commands[cmd_num] = { - "/name", - "/create" - // /rooms - print all public rooms -}; +#define CMD_NAME 0 +#define CMD_CREATE 1 +#define CMD_JOIN 2 +#define CMD_EXIT 3 +#define CMD_ROOMS 4 + +#define USE_IN_ROOM 0 +#define USE_IN_LOBBY 1 +#define USE_ANYWHERE 2 -char **ParseCommand(const char *input, int &arrc); +char **ParseToArg(const char *input, int &arrc); unsigned long hash(const char *str); +struct cmd_info { + char name[15]; + unsigned long name_hash; + int lobby_cmd; // USE_IN_ROOM, USE_IN_LOBBY, USE_ANYWHERE + int min_argc; + char usage[64]; +}; + +const int cmd_count = 5; +const struct cmd_info cmd[cmd_count] = { + {"/name", hash("/name"), USE_IN_LOBBY, 1, "#Usage: /name *your_good_name*\n"}, + {"/create", hash("/create"), USE_IN_LOBBY, 0, "#Usage: /create [pass-key]\n"}, + {"/join", hash("/join"), USE_IN_LOBBY, 1, "#Usage: /join *id* [pass-key]\n"}, + {"/exit", hash("/exit"), USE_IN_ROOM, 0, "#Usage: /exit\n"}, + {"/rooms", hash("/rooms"), USE_IN_LOBBY, 0, "#Usage: /rooms\n"} // print all public rooms + // if u add cmd, then add define too (see above) + + // IDEA: /clear - clear screen +}; + ChatRoom::~ChatRoom() { while(first) { @@ -37,31 +58,18 @@ void ChatRoom::SendAll(const char *msg, ChatSession *except) p->s->Send(msg); } -void ChatRoom::LeaveMessage(ChatSession *except) -{ - if(it_lobby) - return; - - const char left_msg[] = " has left the chat"; - const char *name = except->GetName(); - - int len = strlen(name); - char *lmsg = new char[len + sizeof(left_msg) + 2]; - sprintf(lmsg, "%s%s\n", name, left_msg); - this->SendAll(lmsg, except); - delete[] lmsg; -} - void ChatRoom::HandleMessage(ChatSession *ses, const char *str) { if(str[0] == '/') { // if user sent a command int argc = 0; - char **argv = 0; - argv = ParseCommand(str, argc); - + char **argv = ParseToArg(str, argc); this->HandleCommand(ses, argc, argv); + + for(int i = 0; i < argc; i++) + delete[] argv[i]; + delete[] argv; } - else if(!it_lobby) { + else if(code != std_id_lobby) { char *msg = new char[max_msg_len]; sprintf(msg, "%s: %s\n", ses->GetName(), str); @@ -71,54 +79,83 @@ void ChatRoom::HandleMessage(ChatSession *ses, const char *str) } } -void ChatRoom::HandleCommand(ChatSession *s, int cmd_counter, - char **commands) +void ChatRoom::HandleCommand(ChatSession *ses, int count, + char **argvar) { - unsigned long cmd = -1; - cmd = hash(commands[0]); + unsigned long hash_cmd = -1; + hash_cmd = hash(argvar[0]); - switch(cmd) - { - case CMD_NAME: { - if(!it_lobby) { - s->Send("You can use this command only in lobby\n"); - break; - } + int what_command = -1; + for(int i = 0; i < cmd_count; i++) { + if(cmd[i].name_hash == hash_cmd) { + what_command = i; + break; + } + } - if(cmd_counter == 1) { - s->Send("Usage: /name your_good_name\n"); - break; - } + if(what_command == -1) + return ses->Send("#Unknown command. Use: /help\n"); - int len = strlen(commands[1]); - if(len > max_name_len || len < 3) { - s->Send("Incorrect name. Name length from 3 to 18 chars\n"); - break; - } + const char onlyroom_msg[] = "#You can use this command only in rooms!\n"; + const char onlylobby_msg[] = "#You can use this command only in lobby!\n"; + const char initname_msg[] = "#First come up with name!\n"; + + // scope of command: + if(cmd[what_command].lobby_cmd == USE_IN_ROOM && code == std_id_lobby) + return ses->Send(onlyroom_msg); + else if(cmd[what_command].lobby_cmd == USE_IN_LOBBY && code != std_id_lobby) + return ses->Send(onlylobby_msg); + + // right usage: + if(cmd[what_command].min_argc > count-1) + return ses->Send(cmd[what_command].usage); - s->ChangeName(commands[1]); + // name check: + if((!ses->GetName()) && what_command != CMD_NAME) + return ses->Send(initname_msg); + + switch(what_command) { + case CMD_NAME: { + int len = strlen(argvar[1]); + if(len > max_name_len || len < 3) + return ses->Send("#Incorrect name. Name length from 3 to 18 chars\n"); + + ses->SetName(argvar[1]); break; } case CMD_CREATE: { - if(!it_lobby) { - s->Send("You can use this command only in lobby\n"); - break; - } - if(!s->GetName()) { - s->Send("Before you can use this command, use /name\n"); - break; - } + int id = the_server->AddRoom(); - //int id = the_s->AddRoom(); - //the_s->AddSessionToRoom(s, id); + const char fcmsg[] = "#You create a room #"; + const char scmsg[] = " with password "; + char *cmsg = new char[strlen(fcmsg)+strlen(scmsg)+4]; + sprintf(cmsg, "%s%d\n", fcmsg, id); + ses->Send(cmsg); + delete[] cmsg; + the_server->ChangeSessionRoom(this, ses, id); + break; + } + case CMD_JOIN: { + int id = atoi(argvar[1]); + bool success = false; + if(id >= 0) + success = the_server->ChangeSessionRoom(this, ses, id); + + if(!success) + ses->Send("#Room with that id didn't exist\n"); + + break; + } + case CMD_EXIT: { + the_server->GotoLobby(this, ses); break; } + case CMD_ROOMS: { - default: { - s->Send("Unknown command. Use: /help\n"); break; } + default: break; } } @@ -128,10 +165,40 @@ void ChatRoom::AddSession(ChatSession *ses) p->next = first; p->s = ses; first = p; + + if(code == std_id_lobby) + return; + + const char welcome_msg[] = "Welcome to the room #"; + const char entered_msg[] = " has entered the room"; + + const char *name = ses->GetName(); + + char *wmsg = new char[sizeof(welcome_msg) + 2]; + sprintf(wmsg, "#%s%d\n", welcome_msg, code); + ses->Send(wmsg); + delete[] wmsg; + + char *emsg = new char[strlen(name) + sizeof(entered_msg) + 2]; + sprintf(emsg, "#%s%s\n", name, entered_msg); + this->SendAll(emsg, ses); + delete[] emsg; + } void ChatRoom::RemoveSession(ChatSession *ses) { + if(code != std_id_lobby) { + const char left_msg[] = " has left the room"; + const char *name = ses->GetName(); + + int len = strlen(name); + char *lmsg = new char[len + sizeof(left_msg) + 2]; + sprintf(lmsg, "#%s%s\n", name, left_msg); + this->SendAll(lmsg, ses); + delete[] lmsg; + } + item **p; for(p = &first; *p; p = &((*p)->next)) { if( ((*p)->s) == ses ) { @@ -139,6 +206,10 @@ void ChatRoom::RemoveSession(ChatSession *ses) *p = tmp->next; // not delete ChatSession! delete tmp; + + if(code != std_id_lobby && !first) + the_server->DeleteRoom(code); + return; } } @@ -146,13 +217,14 @@ void ChatRoom::RemoveSession(ChatSession *ses) void ChatRoom::CloseSession(ChatSession *ses) { + Server *serv = the_server; this->RemoveSession(ses); - the_server->CloseConnection(ses); + serv->CloseConnection(ses); } ////////////////////////////////////////////////////////////// -char **ParseCommand(const char *input, int &arrc) +char **ParseToArg(const char *input, int &arrc) { int max_argv = 5; arrc = 0; @@ -161,12 +233,13 @@ char **ParseCommand(const char *input, int &arrc) int start = 0; for(int i = 0; i < (int) strlen(input)+1; i++) { if(input[i] == ' ' || input[i] == '\0' || input[i] == '\n') { // end - if(start == -1) + if(start == std_id_lobby) continue; int size = i - start; - arr[arrc] = new char[size]; + arr[arrc] = new char[size+1]; memcpy(arr[arrc], input + start, sizeof(char) * size); + arr[arrc][size] = '\0'; start = -1; arrc++; -- cgit v1.2.3-18-g5258