From 6139b74876a5c8417d75c2759ce0baec4ae0e171 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Wed, 25 Nov 2020 19:04:49 +0300 Subject: add second (work with chat) level of abstraction --- src/server/rooms.cpp | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 src/server/rooms.cpp (limited to 'src/server/rooms.cpp') diff --git a/src/server/rooms.cpp b/src/server/rooms.cpp new file mode 100644 index 0000000..624eb88 --- /dev/null +++ b/src/server/rooms.cpp @@ -0,0 +1,192 @@ +#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 +}; + +char **ParseCommand(const char *input, int &arrc); +unsigned long hash(const char *str); + +ChatRoom::~ChatRoom() +{ + while(first) { + item *tmp = first; + first = first->next; + the_server->CloseConnection(tmp->s); + delete tmp; + } +} + +void ChatRoom::SendAll(const char *msg, ChatSession *except) +{ + CONSOLE_LOG("Send message all: %s\n", msg); + item *p; + for(p = first; p; p = p->next) + if(p->s != 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); + + this->HandleCommand(ses, argc, argv); + } + else if(!it_lobby) { + char *msg = new char[max_msg_len]; + sprintf(msg, "%s: %s\n", ses->GetName(), str); + + this->SendAll(msg); + + delete[] msg; + } +} + +void ChatRoom::HandleCommand(ChatSession *s, int cmd_counter, + char **commands) +{ + unsigned long cmd = -1; + cmd = hash(commands[0]); + + switch(cmd) + { + case CMD_NAME: { + if(!it_lobby) { + s->Send("You can use this command only in lobby\n"); + break; + } + + if(cmd_counter == 1) { + s->Send("Usage: /name your_good_name\n"); + break; + } + + 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; + } + + s->ChangeName(commands[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_s->AddRoom(); + //the_s->AddSessionToRoom(s, id); + + break; + } + + default: { + s->Send("Unknown command. Use: /help\n"); + break; + } + } +} + +void ChatRoom::AddSession(ChatSession *ses) +{ + item *p = new item; + p->next = first; + p->s = ses; + first = p; +} + +void ChatRoom::RemoveSession(ChatSession *ses) +{ + item **p; + for(p = &first; *p; p = &((*p)->next)) { + if( ((*p)->s) == ses ) { + item *tmp = *p; + *p = tmp->next; + // not delete ChatSession! + delete tmp; + return; + } + } +} + +void ChatRoom::CloseSession(ChatSession *ses) +{ + this->RemoveSession(ses); + the_server->CloseConnection(ses); +} + +////////////////////////////////////////////////////////////// + +char **ParseCommand(const char *input, int &arrc) +{ + int max_argv = 5; + arrc = 0; + char **arr = new char*[max_argv]; + + 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) + continue; + + int size = i - start; + arr[arrc] = new char[size]; + memcpy(arr[arrc], input + start, sizeof(char) * size); + + start = -1; + arrc++; + if(arrc == max_argv) + break; + } + else if(start == -1) + start = i; + } + + return arr; +} + +unsigned long hash(const char *str) +{ + unsigned long hash = 5381; + char c; + + while( (c = *str++) ) + hash = ((hash << 5) + hash) + c; + + return hash; +} \ No newline at end of file -- cgit v1.2.3-18-g5258