summaryrefslogtreecommitdiffstats
path: root/src/server/ChatServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/ChatServer.cpp')
-rw-r--r--src/server/ChatServer.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/server/ChatServer.cpp b/src/server/ChatServer.cpp
new file mode 100644
index 0000000..6256e55
--- /dev/null
+++ b/src/server/ChatServer.cpp
@@ -0,0 +1,155 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "ChatServer.hpp"
+#include "UserInfo.hpp"
+#include "ChatRoom.hpp"
+
+const int qlen_for_listen = 6;
+
+ChatServer::ChatServer(EventSelector *sel, DatabaseManager *db, int fd)
+ : FdHandler(fd), the_selector(sel), dbase(db)
+{
+ the_selector->Add(this);
+ lobby = new ChatRoom(this, std_id_lobby, 0);
+}
+
+ChatServer::~ChatServer()
+{
+ if(room)
+ delete[] room;
+
+ the_selector->Remove(this);
+}
+
+ChatServer *ChatServer::Start(EventSelector *sel, DatabaseManager *db, int port)
+{
+ int in_d = socket(AF_INET, SOCK_STREAM, 0);
+ if(in_d == -1)
+ return 0;
+
+ int opt = 1;
+ setsockopt(in_d, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ struct sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ int res = bind(in_d, (struct sockaddr*) &addr, sizeof(addr));
+ if(res == -1)
+ return 0;
+
+ res = listen(in_d, qlen_for_listen);
+ if(res == -1)
+ return 0;
+
+ return new ChatServer(sel, db, in_d);
+}
+
+int ChatServer::AddRoom(char *password)
+{
+ if(!room) {
+ room_len = 16;
+ room = new ChatRoom*[room_len];
+ for(int i = 0; i < room_len; i++)
+ room[i] = 0;
+ }
+
+ int id = -1;
+ for(int i = 0; i < room_len; i++) {
+ if(room[i] == 0) {
+ id = i;
+ room[i] = new ChatRoom(this, id, password);
+ break;
+ }
+ }
+
+ if(id == -1) {
+ ChatRoom **tmp = new ChatRoom*[room_len+1];
+ for(int i = 0; i < room_len; i++)
+ tmp[i] = room[i];
+
+ id = room_len;
+ tmp[room_len] = new ChatRoom(this, id, password);
+ room_len += 1;
+
+ delete[] room;
+ room = tmp;
+ }
+
+ return id;
+}
+
+bool ChatServer::DeleteRoom(int id)
+{
+ if(!room[id])
+ return false;
+
+ delete room[id];
+ room[id] = 0;
+
+ return true;
+}
+
+bool ChatServer::RoomExist(int id) const
+{
+ if(!room[id])
+ return false;
+
+ return true;
+}
+
+void ChatServer::GotoLobby(ChatRoom *cur_room, UserInfo *u)
+{
+ cur_room->RemoveSession(u);
+ lobby->AddSession(u);
+ u->SetRoom(lobby);
+}
+
+handle_room_enter ChatServer::ChangeSessionRoom(ChatRoom *cur_room,
+ UserInfo *u, int id, char *pass)
+{
+ if(id < 0 || id >= room_len || !room[id])
+ return enter_noexist;
+
+ const char *secret_word = room[id]->GetSecretPass();
+ CONSOLE_LOG("right pass: %s; user enter pass: %s\n", secret_word, pass);
+ if(secret_word != 0) {
+ if(!pass)
+ return enter_private;
+ if(strcmp(secret_word, pass) != 0)
+ return enter_uncorrect_pass;
+ }
+
+ cur_room->RemoveSession(u);
+ room[id]->AddSession(u);
+ u->SetRoom(room[id]);
+ return enter_success;
+}
+
+void ChatServer::CloseConnection(UserInfo *u)
+{
+ the_selector->Remove(u);
+ delete u;
+}
+
+void ChatServer::Handle(bool r, bool w)
+{
+ if(!r)
+ return;
+
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(addr);
+ int sd = accept(GetFd(), (struct sockaddr*) &addr, &len);
+ if(sd == -1)
+ return;
+
+ UserInfo *u = new UserInfo(lobby, sd);
+ lobby->AddSession(u);
+ the_selector->Add(u);
+} \ No newline at end of file