summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoursoir <chat@joursoir.net>2020-12-09 19:34:04 +0000
committerJoursoir <chat@joursoir.net>2020-12-09 19:34:04 +0000
commit4131de177e36b19b20b8bbdb7bd43b18b6e22690 (patch)
tree7540050cbe152fc1257585f4fd30cf9b020508c0
parent1baf22ad58cc1a9aa9089ca9a09fc80a453cb3c9 (diff)
downloadwant-chat-4131de177e36b19b20b8bbdb7bd43b18b6e22690.tar.gz
want-chat-4131de177e36b19b20b8bbdb7bd43b18b6e22690.tar.bz2
want-chat-4131de177e36b19b20b8bbdb7bd43b18b6e22690.zip
clui: architecture go to base class for clients; fix bugs
-rw-r--r--src/client/ClientBase.cpp28
-rw-r--r--src/client/ClientBase.hpp8
-rw-r--r--src/client/clui/Client.cpp65
-rw-r--r--src/client/clui/Client.hpp55
-rw-r--r--src/client/clui/Makefile4
-rw-r--r--src/client/clui/clui.cpp28
-rw-r--r--src/client/clui/clui.hpp8
-rw-r--r--src/client/clui/main.cpp (renamed from src/client/clui/client.cpp)14
-rw-r--r--src/client/clui/user.cpp153
-rw-r--r--src/client/clui/user.hpp32
-rw-r--r--src/const_vars.hpp14
11 files changed, 178 insertions, 231 deletions
diff --git a/src/client/ClientBase.cpp b/src/client/ClientBase.cpp
index fed4c32..aa54365 100644
--- a/src/client/ClientBase.cpp
+++ b/src/client/ClientBase.cpp
@@ -9,8 +9,8 @@
#include "ClientBase.hpp"
-ClientBase::ClientBase(const char* ip, int port) : in_buf_used(0),
- out_buf_used(0), exit_flag(false)
+ClientBase::ClientBase(const char* ip, int port)
+ : out_buf_used(0), exit_flag(false), connection(true)
{
fd = CreateSocket(ip, port);
}
@@ -50,6 +50,8 @@ int ClientBase::CreateSocket(const char* ip, int port)
int ClientBase::Run()
{
+ if(exit_flag)
+ return 0;
HandleActions();
int recive = read(fd, out_buffer+out_buf_used,
@@ -62,9 +64,11 @@ int ClientBase::Run()
else if(recive > 0)
out_buf_used += recive;
else {
- strcpy(out_buffer, "Server closed the connection. Use ESC to exit.");
- ShowMessage(out_buffer);
- //room->AddMessage(out_buffer, system_msg);
+ if(connection) {
+ strcpy(out_buffer, "Server closed the connection. Use ESC to exit.");
+ AddMessage(out_buffer, system_msg);
+ connection = false;
+ }
}
if(out_buf_used > 0) {
@@ -82,14 +86,22 @@ int ClientBase::Run()
buf += 1;
}
- //room->AddMessage(buf, spec_msg);
- ShowMessage(buf);
+ AddMessage(buf, spec_msg);
memmove(out_buffer, out_buffer + i + 1, out_buf_used - i - 1);
out_buf_used -= i + 1;
break;
}
}
}
-
return 1;
+}
+
+void ClientBase::SendMessage(const char *msg)
+{
+ int len = strlen(msg) + 1;
+ char *buf = new char[len];
+ strcpy(buf, msg);
+ buf[len-1] = '\n';
+
+ write(fd, buf, len * sizeof(char));
} \ No newline at end of file
diff --git a/src/client/ClientBase.hpp b/src/client/ClientBase.hpp
index 425929f..387505c 100644
--- a/src/client/ClientBase.hpp
+++ b/src/client/ClientBase.hpp
@@ -6,21 +6,23 @@
class ClientBase {
protected:
int fd;
- char in_buffer[max_usermsg_len]; // for input
- int in_buf_used;
char out_buffer[max_msg_len]; // for message
int out_buf_used;
bool exit_flag;
+ bool connection;
public:
ClientBase(const char* ip, int port);
virtual ~ClientBase();
int ConstuctorError() const { return fd > -1 ? 0 : 1; }
int Run();
+ void BreakLoop() { exit_flag = true; }
+
virtual void HandleActions() {}
- virtual void ShowMessage(const char *msg) {}
+ virtual void AddMessage(const char *msg, int type) {}
+ void SendMessage(const char *msg);
private:
int CreateSocket(const char* ip, int port);
};
diff --git a/src/client/clui/Client.cpp b/src/client/clui/Client.cpp
new file mode 100644
index 0000000..36859ce
--- /dev/null
+++ b/src/client/clui/Client.cpp
@@ -0,0 +1,65 @@
+#include <string.h>
+
+#include "Client.hpp"
+#include "clui.hpp"
+
+const int key_enter = 10;
+const int key_escape = 27;
+const int key_backspace = 127;
+
+void Client::HandleActions()
+{
+ int key = room->InputGetch();
+ switch(key)
+ {
+ case key_escape: {
+ this->BreakLoop();
+ break;
+ }
+ case ' '...'~': { // ascii table 32...126
+ AddCharToBuffer(key);
+ room->AddCharToSendMsg(key);
+ break;
+ }
+ case '\n': { // send message
+ if(in_buf_used <= 0)
+ return;
+ SendMessage(in_buffer);
+ memset(in_buffer, 0, (in_buf_used+1)*sizeof(char));
+ in_buf_used = 0;
+
+ room->InputClear();
+ room->SetInputCursor(1, 1);
+ break;
+ }
+ case key_backspace: {
+ RemoveCharFromBuffer();
+ room->RemoveCharFromMsg();
+ break;
+ }
+ default: break;
+ }
+}
+
+void Client::AddMessage(const char *msg, int type)
+{
+ room->AddMessage(msg, type);
+}
+
+void Client::AddCharToBuffer(char ch)
+{
+ if(in_buf_used >= max_usermsg_len-1)
+ return;
+
+ in_buffer[in_buf_used] = ch;
+ in_buf_used++;
+}
+
+void Client::RemoveCharFromBuffer()
+{
+ if(in_buf_used <= 0)
+ return;
+
+ in_buffer[in_buf_used] = '\0';
+ in_buf_used--;
+} \ No newline at end of file
diff --git a/src/client/clui/Client.hpp b/src/client/clui/Client.hpp
new file mode 100644
index 0000000..37bc3e0
--- /dev/null
+++ b/src/client/clui/Client.hpp
@@ -0,0 +1,55 @@
+#ifndef WC_CLUI_CLIENT_H
+#define WC_CLUI_CLIENT_H
+
+#include "../../const_vars.hpp"
+#include "../ClientBase.hpp"
+
+class ChatRoom;
+
+class Client : public ClientBase {
+ char in_buffer[max_usermsg_len]; // for input
+ int in_buf_used;
+
+ bool exit_flag;
+
+ ChatRoom *room;
+public:
+ Client(const char* ip, int port, ChatRoom *i_room)
+ : ClientBase(ip, port), in_buf_used(0),
+ exit_flag(false), room(i_room) {}
+ ~Client() {}
+
+ virtual void HandleActions();
+ virtual void AddMessage(const char *msg, int type);
+private:
+ void AddCharToBuffer(char ch);
+ void RemoveCharFromBuffer();
+};
+
+
+/*class Client {
+ int fd;
+ char in_buffer[max_usermsg_len]; // for input
+ int in_buf_used;
+
+ char out_buffer[max_msg_len]; // for message
+ int out_buf_used;
+
+ bool exit_flag;
+
+ Client(int i_fd) : fd(i_fd), in_buf_used(0),
+ out_buf_used(0), exit_flag(false) {}
+public:
+ ~Client() { close(fd); }
+
+ static Client *Start(const char* ip, int port);
+ void Run(ChatRoom *room);
+ void BreakLoop() { exit_flag = true; }
+ void HandleButton(ChatRoom *room);
+
+ void AddCharToBuffer(char ch);
+ void RemoveCharFromBuffer();
+ void SendMessage();
+};*/
+
+#endif \ No newline at end of file
diff --git a/src/client/clui/Makefile b/src/client/clui/Makefile
index 071462b..b77c8f6 100644
--- a/src/client/clui/Makefile
+++ b/src/client/clui/Makefile
@@ -1,7 +1,7 @@
CPP = g++
CPPFLAGS = -Wall -g -lncurses
-SOURCES = client.cpp clui.cpp user.cpp
-OBJECTS = $(SOURCES:.cpp=.o)
+SOURCES = main.cpp clui.cpp Client.cpp ../ClientBase.cpp
+OBJECTS = main.o clui.o Client.o ClientBase.o
EXECUTABLE = client
.PHONY: all clean
diff --git a/src/client/clui/clui.cpp b/src/client/clui/clui.cpp
index 78fd226..a7f908e 100644
--- a/src/client/clui/clui.cpp
+++ b/src/client/clui/clui.cpp
@@ -55,18 +55,19 @@ ChatRoom::~ChatRoom()
if(input)
delete input;
- // #TODO:
- /* if(first) ... delete message */
+ while(first) {
+ message *tmp = first;
+ first = first->prev;
+ delete tmp;
+ }
}
-void ChatRoom::AddMessage(char *msg, int type)
+void ChatRoom::AddMessage(const char *msg, int type)
{
message *recent_msg = new message;
- int lines = 1;
int len = strlen(msg);
- if(len > CHAT_WIDTH-2 + CHAT_WIDTH-2) lines = 3;
- else if(len > CHAT_WIDTH-2) lines = 2;
+ int lines = (len / oneline_len) + 1;
strcpy(recent_msg->msg, msg);
recent_msg->num_lines = lines;
@@ -84,13 +85,13 @@ void ChatRoom::ChatRedraw()
return;
chat->Clear(false);
- int available_lines = CHAT_HEIGHT - 2;
+ int available_lines = lines_in_chat;
bool remove = false;
message *tmp;
message *last;
for(message *m = first; m; m = m->prev) {
- if(available_lines-1 >= m->num_lines) {
+ if(available_lines >= m->num_lines) {
PrintMessage(available_lines, m);
available_lines -= m->num_lines;
last = m;
@@ -119,25 +120,22 @@ void ChatRoom::PrintMessage(int line, message *m)
{
WINDOW *win = this->chat->GetWindow();
int need_print = m->num_lines;
- int maxlen_oneline = CHAT_WIDTH-2;
while(need_print != 0) {
if(m->type == system_msg) wattron(win, A_ITALIC);
else wattron(win, A_BOLD);
-
wmove(win, line-need_print+1, 1);
- char *tmp = new char[maxlen_oneline];
- int str = maxlen_oneline * (m->num_lines - need_print);
- memcpy(tmp, m->msg + str, maxlen_oneline);
+ char *tmp = new char[oneline_len];
+ int str = oneline_len * (m->num_lines - need_print);
+ memcpy(tmp, m->msg + str, oneline_len);
wprintw(win, tmp);
- need_print--;
-
if(m->type == system_msg) wattroff(win, A_ITALIC);
else wattroff(win, A_BOLD);
delete[] tmp;
+ need_print--;
}
}
diff --git a/src/client/clui/clui.hpp b/src/client/clui/clui.hpp
index 0373f95..e337aa9 100644
--- a/src/client/clui/clui.hpp
+++ b/src/client/clui/clui.hpp
@@ -1,10 +1,10 @@
// CLUI - Command Line User Interface
-#ifndef COMMANDLINEUI_H
-#define COMMANDLINEUI_H
+#ifndef WC_CLUI_H
+#define WC_CLUI_H
#include <ncurses.h>
-#include "../const_vars.hpp"
+#include "../../const_vars.hpp"
class Interface_wc {
WINDOW *w;
@@ -41,7 +41,7 @@ public:
~ChatRoom();
// for chat:
- void AddMessage(char *msg, int type);
+ void AddMessage(const char *msg, int type);
// for players:
//void AddPlayer()
diff --git a/src/client/clui/client.cpp b/src/client/clui/main.cpp
index 83f8ef0..fd77708 100644
--- a/src/client/clui/client.cpp
+++ b/src/client/clui/main.cpp
@@ -3,8 +3,9 @@
#include <string.h>
#include <unistd.h>
-#include "../config.hpp"
-#include "user.hpp"
+#include "../../config.hpp"
+#include "Client.hpp"
+#include "clui.hpp"
int main(int argc, char *argv[])
{
@@ -19,16 +20,17 @@ int main(int argc, char *argv[])
return 1;
}
- Client *user = Client::Start(SERVER_IP, SERVER_PORT);
- if(!user) {
+ ChatRoom *room = new ChatRoom();
+ Client *user = new Client(SERVER_IP, SERVER_PORT, room);
+ if(user->ConstuctorError()) {
endwin();
perror("server");
return 1;
}
- ChatRoom *room = new ChatRoom();
- user->Run(room);
+ while(user->Run());
delete room;
+ delete user;
endwin();
return 0;
diff --git a/src/client/clui/user.cpp b/src/client/clui/user.cpp
deleted file mode 100644
index d075751..0000000
--- a/src/client/clui/user.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-#include <string.h>
-#include <unistd.h>
-#include <netinet/in.h> // for sockaddr_in
-#include <arpa/inet.h> // for iten_aton
-#include <sys/types.h> // for bind, connect
-#include <sys/socket.h> // for bind, connect
-#include <fcntl.h>
-#include <cerrno>
-#include <stdio.h>
-
-#include "user.hpp"
-
-const int key_enter = 10;
-const int key_escape = 27;
-const int key_backspace = 127;
-
-Client *Client::Start(const char* ip, int port)
-{
- int client;
- client = socket(AF_INET, SOCK_STREAM, 0);
- if(client == -1) return 0;
-
- // remove "port sticking" aka socket in TIME_WAIT
- int opt = 1;
- setsockopt(client, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
-
- /* call bind optional, the system chooses
- the address automatically */
-
- struct sockaddr_in server_adress;
- server_adress.sin_family = AF_INET;
- server_adress.sin_port = htons(port);
- if(!inet_aton(ip, &(server_adress.sin_addr))) return 0;
-
- int res = connect(client, (struct sockaddr*) &server_adress,
- sizeof(server_adress));
- if(res == -1) return 0;
-
- return new Client(client);
-}
-
-void Client::Run(ChatRoom *room)
-{
- unsigned int usecs = 0100000;
- int flags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
- int cls = false;
- do {
- this->HandleButton(room);
-
- int recive = read(fd, out_buffer+out_buf_used,
- sizeof(out_buffer)-out_buf_used);
-
- if(recive < 0) {
- if(errno != EINTR && errno != EAGAIN)
- break;
- }
- else if(recive > 0)
- out_buf_used += recive;
- else {
- if(!cls) {
- strcpy(out_buffer, "Server closed the connection. Use ESC to exit.");
- room->AddMessage(out_buffer, system_msg);
- cls = true;
- }
- }
-
- if(out_buf_used > 0) {
- /* warning: if we get a (message without '\n') > max_msg_len then
- this code will not work */
- for(int i = 0; i < out_buf_used; i++) {
- if(out_buffer[i] == '\n') {
- out_buffer[i] = 0;
-
- // in first char have may spec-symbol, check it:
- int spec_msg = usual_msg;
- char *buf = out_buffer;
- if(out_buffer[0] == system_char) {
- spec_msg = system_msg;
- buf += 1;
- }
-
- room->AddMessage(buf, spec_msg);
- memmove(out_buffer, out_buffer + i + 1, out_buf_used - i - 1);
- out_buf_used -= i + 1;
- break;
- }
- }
- }
-
- usleep(usecs);
- } while (!exit_flag);
-}
-
-void Client::HandleButton(ChatRoom *room)
-{
- int key = room->InputGetch();
- switch(key)
- {
- case key_escape: {
- this->BreakLoop();
- break;
- }
- case ' '...'~': { // ascii table 32...126
- AddCharToBuffer(key);
- room->AddCharToSendMsg(key);
- break;
- }
- case '\n': { // send message
- SendMessage();
- room->InputClear();
- room->SetInputCursor(1, 1);
- break;
- }
- case key_backspace: {
- RemoveCharFromBuffer();
- room->RemoveCharFromMsg();
- break;
- }
- default: break;
- }
-}
-
-void Client::AddCharToBuffer(char ch)
-{
- if(in_buf_used >= max_usermsg_len-1)
- return;
-
- in_buffer[in_buf_used] = ch;
- in_buf_used++;
-}
-
-void Client::RemoveCharFromBuffer()
-{
- if(in_buf_used <= 0)
- return;
-
- in_buffer[in_buf_used] = '\0';
- in_buf_used--;
-}
-
-void Client::SendMessage()
-{
- if(in_buf_used <= 0)
- return;
-
- in_buffer[in_buf_used] = '\n';
-
- write(fd, in_buffer, (in_buf_used+1)*sizeof(char));
- memset(in_buffer, 0, (in_buf_used+1)*sizeof(char));
- in_buf_used = 0;
-} \ No newline at end of file
diff --git a/src/client/clui/user.hpp b/src/client/clui/user.hpp
deleted file mode 100644
index a203320..0000000
--- a/src/client/clui/user.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef USER_H
-#define USER_H
-
-#include "clui.hpp"
-#include "../const_vars.hpp"
-
-class Client {
- int fd;
- char in_buffer[max_usermsg_len]; // for input
- int in_buf_used;
-
- char out_buffer[max_msg_len]; // for message
- int out_buf_used;
-
- bool exit_flag;
-
- Client(int i_fd) : fd(i_fd), in_buf_used(0),
- out_buf_used(0), exit_flag(false) {}
-public:
- ~Client() { close(fd); }
-
- static Client *Start(const char* ip, int port);
- void Run(ChatRoom *room);
- void BreakLoop() { exit_flag = true; }
- void HandleButton(ChatRoom *room);
-
- void AddCharToBuffer(char ch);
- void RemoveCharFromBuffer();
- void SendMessage();
-};
-
-#endif \ No newline at end of file
diff --git a/src/const_vars.hpp b/src/const_vars.hpp
index 66d31d9..f34ab7f 100644
--- a/src/const_vars.hpp
+++ b/src/const_vars.hpp
@@ -1,22 +1,20 @@
-#ifndef CONSTVARS_H
-#define CONSTVARS_H
-
-/*
- * In chat messages look like that:
- * Knight385: Hello, guys!
- *
-*/
+#ifndef WC_CONSTVARS_H
+#define WC_CONSTVARS_H
+// === Authorization info ==== //
const int max_name_len = 18;
const int min_name_len = 3;
const int max_player_lenpass = 24;
const int min_player_lenpass = 4;
+// === UI info === //
const int oneline_len = 57;
const int max_usermsg_len = oneline_len * 3 - max_name_len - 2; // ": " = 2
// 57 * 3 - 18 - 2 = 151
const int max_msg_len = oneline_len * 3; // 57*3 = 171
+const int lines_in_chat = 18;
+// === Message info === //
const int usual_msg = 0; // no first char
const int system_msg = 1;
const char system_char = '#';