diff options
author | Joursoir <chat@joursoir.net> | 2020-12-08 12:48:16 +0000 |
---|---|---|
committer | Joursoir <chat@joursoir.net> | 2020-12-08 12:48:16 +0000 |
commit | 27cd9aded215835ffde615153600476bf9be2473 (patch) | |
tree | 0018a18a3d1b5891321d8218001c02128af82380 /src/client | |
parent | f7bd80577164da7540ad93fb2fa93df38168133b (diff) | |
download | want-chat-27cd9aded215835ffde615153600476bf9be2473.tar.gz want-chat-27cd9aded215835ffde615153600476bf9be2473.tar.bz2 want-chat-27cd9aded215835ffde615153600476bf9be2473.zip |
create base class for all client, add some functionality to gui
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/ClientBase.cpp | 95 | ||||
-rw-r--r-- | src/client/ClientBase.hpp | 28 | ||||
-rw-r--r-- | src/client/gui/Client.cpp | 6 | ||||
-rw-r--r-- | src/client/gui/Client.hpp | 18 | ||||
-rw-r--r-- | src/client/gui/Makefile | 4 | ||||
-rw-r--r-- | src/client/gui/OO_FLTK.hpp | 7 | ||||
-rw-r--r-- | src/client/gui/main.cpp (renamed from src/client/gui/client.cpp) | 51 |
7 files changed, 184 insertions, 25 deletions
diff --git a/src/client/ClientBase.cpp b/src/client/ClientBase.cpp new file mode 100644 index 0000000..fed4c32 --- /dev/null +++ b/src/client/ClientBase.cpp @@ -0,0 +1,95 @@ +#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 "ClientBase.hpp" + +ClientBase::ClientBase(const char* ip, int port) : in_buf_used(0), + out_buf_used(0), exit_flag(false) +{ + fd = CreateSocket(ip, port); +} + +ClientBase::~ClientBase() +{ + if(fd != -1) + close(fd); +} + +int ClientBase::CreateSocket(const char* ip, int port) +{ + int client = socket(AF_INET, SOCK_STREAM, 0); + if(client == -1) return -1; + + // 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 -1; + + int res = connect(client, (struct sockaddr*) &server_adress, + sizeof(server_adress)); + if(res == -1) return -1; + + int flags = fcntl(client, F_GETFL, 0); + fcntl(client, F_SETFL, flags | O_NONBLOCK); + + return client; +} + +int ClientBase::Run() +{ + HandleActions(); + + int recive = read(fd, out_buffer+out_buf_used, + sizeof(out_buffer)-out_buf_used); + + if(recive < 0) { + if(errno != EINTR && errno != EAGAIN) + return 0; + } + 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(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); + ShowMessage(buf); + memmove(out_buffer, out_buffer + i + 1, out_buf_used - i - 1); + out_buf_used -= i + 1; + break; + } + } + } + + return 1; +}
\ No newline at end of file diff --git a/src/client/ClientBase.hpp b/src/client/ClientBase.hpp new file mode 100644 index 0000000..425929f --- /dev/null +++ b/src/client/ClientBase.hpp @@ -0,0 +1,28 @@ +#ifndef WC_CLIENTBASE_H +#define WC_CLIENTBASE_H + +#include "../const_vars.hpp" + +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; +public: + ClientBase(const char* ip, int port); + virtual ~ClientBase(); + int ConstuctorError() const { return fd > -1 ? 0 : 1; } + + int Run(); + virtual void HandleActions() {} + virtual void ShowMessage(const char *msg) {} +private: + int CreateSocket(const char* ip, int port); +}; + +#endif
\ No newline at end of file diff --git a/src/client/gui/Client.cpp b/src/client/gui/Client.cpp new file mode 100644 index 0000000..2465ab7 --- /dev/null +++ b/src/client/gui/Client.cpp @@ -0,0 +1,6 @@ +#include "Client.hpp" + +void Client::ShowMessage(const char *msg) +{ + chat->value(msg); +}
\ No newline at end of file diff --git a/src/client/gui/Client.hpp b/src/client/gui/Client.hpp new file mode 100644 index 0000000..1ab7a84 --- /dev/null +++ b/src/client/gui/Client.hpp @@ -0,0 +1,18 @@ +#ifndef WC_GUI_CLIENT_H +#define WC_GUI_CLIENT_H + +#include "../ClientBase.hpp" +#include "OO_FLTK.hpp" + +class Client : public ClientBase { + ChatBaseOutput *chat; +public: + Client(const char* ip, int port, ChatBaseOutput *cb_out) + : ClientBase(ip, port), chat(cb_out) {} + ~Client() {} + + virtual void HandleActions() {} + virtual void ShowMessage(const char *msg); +}; + +#endif
\ No newline at end of file diff --git a/src/client/gui/Makefile b/src/client/gui/Makefile index 67ff3e2..a72e64d 100644 --- a/src/client/gui/Makefile +++ b/src/client/gui/Makefile @@ -1,7 +1,7 @@ CPP = g++ CPPFLAGS = -Wall -g -lfltk -SOURCES = client.cpp OO_FLTK.cpp -OBJECTS = $(SOURCES:.cpp=.o) +SOURCES = main.cpp OO_FLTK.cpp ../ClientBase.cpp Client.cpp +OBJECTS = main.o OO_FLTK.o ClientBase.o Client.o EXECUTABLE = client .PHONY: all clean diff --git a/src/client/gui/OO_FLTK.hpp b/src/client/gui/OO_FLTK.hpp index 2f52f97..b581321 100644 --- a/src/client/gui/OO_FLTK.hpp +++ b/src/client/gui/OO_FLTK.hpp @@ -1,3 +1,6 @@ +#ifndef WC_OOFLTK_H +#define WC_OOFLTK_H + #include <FL/Fl.H> #include <FL/Fl_Box.H> #include <FL/Fl_Input.H> @@ -23,4 +26,6 @@ class ChatBaseOutput : public Fl_Multiline_Output { public: ChatBaseOutput(int x, int y, int w, int h, const char *lb = 0); ~ChatBaseOutput() {} -};
\ No newline at end of file +}; + +#endif
\ No newline at end of file diff --git a/src/client/gui/client.cpp b/src/client/gui/main.cpp index d365288..3839454 100644 --- a/src/client/gui/client.cpp +++ b/src/client/gui/main.cpp @@ -1,10 +1,11 @@ +#include <cerrno> #include <FL/Fl.H> +#include <FL/fl_ask.H> #include <FL/Fl_Window.H> -#include <FL/Fl_Box.H> -#include <FL/Fl_Multiline_Output.H> -#include <FL/Fl_Input.H> #include "OO_FLTK.hpp" +#include "../../config.hpp" +#include "Client.hpp" const int spacing = 20; const int border = 2; @@ -26,48 +27,54 @@ int main(int argc, char **argv) win->color(FL_BLACK); // - BoxOutline *ol_chat = new BoxOutline( - spacing, spacing, chat_w+border*2, chat_h+border*2); + + BoxOutline ol_chat(spacing, spacing, chat_w+border*2, chat_h+border*2); ChatBaseOutput *chat = new ChatBaseOutput( spacing+border, spacing+border, chat_w, chat_h); // only for test, please not going to beat me :) - char buffer[2048] = ""; - for(int i = 0; i < 18; i++) - sprintf(buffer, "%sNickname: some text some text some text some text some te\n", buffer); - chat->value(buffer); + /*char buffer[2048] = ""; + for(int i = 0; i < 17; i++) + sprintf(buffer, "%s\n", buffer); + sprintf(buffer, "%sWelcome to WantChat! What is your name?\n", buffer); + chat->value(buffer);*/ // int start_players_x = spacing + border + chat_w + border + spacing; - BoxOutline *ol_players = new BoxOutline( - start_players_x, spacing, player_w+border*2, player_h+border*2); + BoxOutline ol_players(start_players_x, spacing, player_w+border*2, player_h+border*2); ChatBaseOutput *players = new ChatBaseOutput( start_players_x + border, spacing+border, player_w, player_h); // only for test, please not going to beat me :) (x2) - char buffer1[1024] = ""; + /*char buffer1[1024] = ""; for(int i = 0; i < 18; i++) sprintf(buffer1, "%sHackerspronickname\n", buffer1); - players->value(buffer1); + players->value(buffer1);*/ // int start_input_y = spacing + border + chat_h + border + spacing; - BoxOutline *outline_input = new BoxOutline( - spacing, start_input_y, input_w+border*2, input_h+border*2); + BoxOutline ol_input(spacing, start_input_y, input_w+border*2, input_h+border*2); ChatInput *input = new ChatInput(spacing+border, start_input_y+border, input_w, input_h); + // win->end(); win->show(); - return Fl::run(); -} -// 59 - 1 - 20 + Client *user = new Client(SERVER_IP, SERVER_PORT, chat); + if(user->ConstuctorError()) { + perror("server"); + fl_choice("Server error", "Exit", 0, 0); + win->hide(); + } + + while(Fl::wait()) + { + user->Run(); + } -/* I need this widgets: -- Button -- Inputbox -- Box */
\ No newline at end of file + return 0; +}
\ No newline at end of file |