From 27cd9aded215835ffde615153600476bf9be2473 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Tue, 8 Dec 2020 12:48:16 +0000 Subject: create base class for all client, add some functionality to gui --- src/client/ClientBase.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++ src/client/ClientBase.hpp | 28 ++++++++++++++ src/client/gui/Client.cpp | 6 +++ src/client/gui/Client.hpp | 18 +++++++++ src/client/gui/Makefile | 4 +- src/client/gui/OO_FLTK.hpp | 7 +++- src/client/gui/client.cpp | 73 ----------------------------------- src/client/gui/main.cpp | 80 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 235 insertions(+), 76 deletions(-) create mode 100644 src/client/ClientBase.cpp create mode 100644 src/client/ClientBase.hpp create mode 100644 src/client/gui/Client.cpp create mode 100644 src/client/gui/Client.hpp delete mode 100644 src/client/gui/client.cpp create mode 100644 src/client/gui/main.cpp 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 +#include +#include // for sockaddr_in +#include // for iten_aton +#include // for bind, connect +#include // for bind, connect +#include +#include + +#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 #include #include @@ -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/client.cpp deleted file mode 100644 index d365288..0000000 --- a/src/client/gui/client.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include - -#include "OO_FLTK.hpp" - -const int spacing = 20; -const int border = 2; - -const int chat_w = 695; -const int chat_h = 440; -const int player_w = 225; -const int player_h = chat_h; -const int input_w = chat_w + border + spacing + border + player_w; -const int input_h = 40; // 55 - -const int win_w = spacing + border + (input_w) + border + spacing; -const int win_h = spacing + border + chat_h + border + - spacing + border + input_h + border + spacing; - -int main(int argc, char **argv) -{ - Fl_Window *win = new Fl_Window(win_w, win_h, "WantChat"); - win->color(FL_BLACK); - - // - BoxOutline *ol_chat = new BoxOutline( - 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); - - // - - 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); - 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] = ""; - for(int i = 0; i < 18; i++) - sprintf(buffer1, "%sHackerspronickname\n", 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); - ChatInput *input = new ChatInput(spacing+border, - start_input_y+border, input_w, input_h); - // - - win->end(); - win->show(); - return Fl::run(); -} - -// 59 - 1 - 20 - -/* I need this widgets: -- Button -- Inputbox -- Box */ \ No newline at end of file diff --git a/src/client/gui/main.cpp b/src/client/gui/main.cpp new file mode 100644 index 0000000..3839454 --- /dev/null +++ b/src/client/gui/main.cpp @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +#include "OO_FLTK.hpp" +#include "../../config.hpp" +#include "Client.hpp" + +const int spacing = 20; +const int border = 2; + +const int chat_w = 695; +const int chat_h = 440; +const int player_w = 225; +const int player_h = chat_h; +const int input_w = chat_w + border + spacing + border + player_w; +const int input_h = 40; // 55 + +const int win_w = spacing + border + (input_w) + border + spacing; +const int win_h = spacing + border + chat_h + border + + spacing + border + input_h + border + spacing; + +int main(int argc, char **argv) +{ + Fl_Window *win = new Fl_Window(win_w, win_h, "WantChat"); + win->color(FL_BLACK); + + // + + 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 < 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(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] = ""; + for(int i = 0; i < 18; i++) + sprintf(buffer1, "%sHackerspronickname\n", buffer1); + players->value(buffer1);*/ + + // + + int start_input_y = spacing + border + chat_h + border + spacing; + 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(); + + 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(); + } + + return 0; +} \ No newline at end of file -- cgit v1.2.3-18-g5258