summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoursoir <chat@joursoir.net>2020-11-27 01:21:10 +0300
committerJoursoir <chat@joursoir.net>2020-11-27 01:21:10 +0300
commit67cdd15d97b14dd92de28fdbdb2770187c94e338 (patch)
tree1a3acc83f0187111404047f407b042671ff5d4e0
parent6139b74876a5c8417d75c2759ce0baec4ae0e171 (diff)
downloadwant-chat-67cdd15d97b14dd92de28fdbdb2770187c94e338.tar.gz
want-chat-67cdd15d97b14dd92de28fdbdb2770187c94e338.tar.bz2
want-chat-67cdd15d97b14dd92de28fdbdb2770187c94e338.zip
one more fix chat, support spec-messages, add exit from program :)
-rw-r--r--src/client/Makefile18
-rw-r--r--src/client/client.cpp3
-rw-r--r--src/client/clui.cpp23
-rw-r--r--src/client/clui.hpp10
-rw-r--r--src/client/user.cpp63
-rw-r--r--src/client/user.hpp11
6 files changed, 81 insertions, 47 deletions
diff --git a/src/client/Makefile b/src/client/Makefile
new file mode 100644
index 0000000..071462b
--- /dev/null
+++ b/src/client/Makefile
@@ -0,0 +1,18 @@
+CPP = g++
+CPPFLAGS = -Wall -g -lncurses
+SOURCES = client.cpp clui.cpp user.cpp
+OBJECTS = $(SOURCES:.cpp=.o)
+EXECUTABLE = client
+
+.PHONY: all clean
+
+all: $(EXECUTABLE)
+
+clean:
+ rm -rf $(OBJECTS) $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CPP) $(CPPFLAGS) -o $(EXECUTABLE) $(OBJECTS)
+
+$(OBJECTS):
+ $(CPP) -c $(CPPFLAGS) $(SOURCES) \ No newline at end of file
diff --git a/src/client/client.cpp b/src/client/client.cpp
index 8f6a9ff..7f092cc 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -11,9 +11,8 @@ static int port = 3030;
int main(int argc, char *argv[])
{
initscr();
- cbreak();
+ //raw();
noecho();
- curs_set(false);
int rows, columns;
getmaxyx(stdscr, rows, columns);
diff --git a/src/client/clui.cpp b/src/client/clui.cpp
index 12bae03..78fd226 100644
--- a/src/client/clui.cpp
+++ b/src/client/clui.cpp
@@ -1,9 +1,7 @@
#include <string.h>
-#include <ncurses.h>
-
#include <unistd.h>
+
#include "clui.hpp"
-#include "../const_vars.hpp"
#define CHAT_HEIGHT 20
#define CHAT_WIDTH 59
@@ -42,6 +40,8 @@ ChatRoom::ChatRoom() : first(0)
chat = new Interface_wc(CHAT_HEIGHT, CHAT_WIDTH, 0, 0, 0);
players = new Interface_wc(PLAYERS_HEIGHT, PLAYERS_WIDTH, 0, 60, 0);
input = new Interface_wc(INPUT_HEIGHT, INPUT_WIDTH, 20, 0, 0);
+ nodelay(input->GetWindow(), true);
+ keypad(input->GetWindow(), true);
i_nx = 1;
i_ny = 1;
}
@@ -59,7 +59,7 @@ ChatRoom::~ChatRoom()
/* if(first) ... delete message */
}
-void ChatRoom::AddMessage(char *msg)
+void ChatRoom::AddMessage(char *msg, int type)
{
message *recent_msg = new message;
@@ -70,6 +70,7 @@ void ChatRoom::AddMessage(char *msg)
strcpy(recent_msg->msg, msg);
recent_msg->num_lines = lines;
+ recent_msg->type = type;
recent_msg->prev = first;
first = recent_msg;
@@ -116,11 +117,14 @@ void ChatRoom::ChatRedraw()
void ChatRoom::PrintMessage(int line, message *m)
{
- WINDOW *win = this->GetChatWin();
+ 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];
@@ -130,18 +134,21 @@ void ChatRoom::PrintMessage(int line, message *m)
wprintw(win, tmp);
need_print--;
+ if(m->type == system_msg) wattroff(win, A_ITALIC);
+ else wattroff(win, A_BOLD);
+
delete[] tmp;
}
}
bool ChatRoom::AddCharToSendMsg(char ch)
{
- if(i_ny == 2 && i_nx == max_line_len/2-1)
+ if(i_ny == 2 && i_nx == max_usermsg_len/2-1)
return 0;
mvwaddch(input->GetWindow(), i_ny, i_nx, ch);
i_nx++;
- if(i_nx >= max_line_len/2-1) {
+ if(i_nx >= max_usermsg_len/2-1) {
if(i_ny == 1) {
i_ny++;
i_nx = 1;
@@ -163,7 +170,7 @@ bool ChatRoom::RemoveCharFromMsg()
i_nx--;
if(i_nx < 1) {
i_ny--;
- i_nx = max_line_len/2-1;
+ i_nx = max_usermsg_len/2-1;
}
mvwaddch(input->GetWindow(), i_ny, i_nx, ' ');
wmove(input->GetWindow(), i_ny, i_nx);
diff --git a/src/client/clui.hpp b/src/client/clui.hpp
index de47177..0373f95 100644
--- a/src/client/clui.hpp
+++ b/src/client/clui.hpp
@@ -4,6 +4,7 @@
#define COMMANDLINEUI_H
#include <ncurses.h>
+#include "../const_vars.hpp"
class Interface_wc {
WINDOW *w;
@@ -29,8 +30,9 @@ class ChatRoom {
int i_nx, i_ny;
struct message {
- char msg[300];
+ char msg[max_msg_len];
int num_lines; // number of lines
+ int type;
message *prev;
};
message *first;
@@ -39,19 +41,17 @@ public:
~ChatRoom();
// for chat:
- void AddMessage(char *msg);
+ void AddMessage(char *msg, int type);
// for players:
//void AddPlayer()
// for input:
+ int InputGetch() { return wgetch(input->GetWindow()); }
bool AddCharToSendMsg(char ch);
bool RemoveCharFromMsg();
void InputClear() { input->Clear(false); }
void SetInputCursor(int y, int x);
-
- WINDOW *GetInputWin() { return input->GetWindow(); }
- WINDOW *GetChatWin() { return chat->GetWindow(); }
private:
// for chat:
void ChatRedraw();
diff --git a/src/client/user.cpp b/src/client/user.cpp
index 91b2450..957665e 100644
--- a/src/client/user.cpp
+++ b/src/client/user.cpp
@@ -1,20 +1,15 @@
#include <string.h>
-#include <unistd.h> // for close
-#include <netinet/in.h> // for iten_aton, iten_ntoa, sockaddr_in
-#include <arpa/inet.h> // for iten_aton, iten_ntoa
+#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> // for fcntl
-#include <cerrno> // for errno
+#include <fcntl.h>
+#include <cerrno>
#include <stdio.h>
#include "user.hpp"
-const int key_esc = 4;
-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;
@@ -42,27 +37,44 @@ Client *Client::Start(const char* ip, int port)
void Client::Run(ChatRoom *room)
{
- unsigned int usecs = 0125000;
+ unsigned int usecs = 0100000;
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
- nodelay(room->GetInputWin(), true);
- curs_set(true);
do {
this->HandleButton(room);
- int recive = read(fd, out_buffer, sizeof(out_buffer));
+ int recive = read(fd, out_buffer+out_buf_used,
+ sizeof(out_buffer)-out_buf_used);
if(recive < 0) {
- if(errno != EINTR && errno != EAGAIN)
+ if(errno != EINTR && errno != EAGAIN)
break;
}
- else if(recive > 0) {
- /* warning: if we get a message >= maxlen_outbuf then
+ else if(recive > 0)
+ out_buf_used += recive;
+
+ if(out_buf_used > 0) {
+ /* warning: if we get a (message without '\n') > max_msg_len then
this code will not work */
- out_buffer[recive-1] = '\0'; // change '\n' to '\0'
- room->AddMessage(out_buffer);
- memset(out_buffer, 0, recive);
+ 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_symbol = usually_msg;
+ char *buf = out_buffer;
+ if(out_buffer[0] == '#') {
+ spec_symbol = system_msg;
+ buf += 1;
+ }
+
+ room->AddMessage(buf, spec_symbol);
+ memmove(out_buffer, out_buffer + i + 1, out_buf_used - i - 1);
+ out_buf_used -= i + 1;
+ break;
+ }
+ }
}
usleep(usecs);
@@ -71,15 +83,14 @@ void Client::Run(ChatRoom *room)
void Client::HandleButton(ChatRoom *room)
{
- int key = wgetch(room->GetInputWin());
+ int key = room->InputGetch();
switch(key)
{
- case key_esc: {
- // #todo: exit
+ case key_escape: {
+ this->BreakLoop();
break;
}
- // ascii table 32...126
- case ' '...'~': {
+ case ' '...'~': { // ascii table 32...126
AddCharToBuffer(key);
room->AddCharToSendMsg(key);
break;
@@ -101,7 +112,7 @@ void Client::HandleButton(ChatRoom *room)
void Client::AddCharToBuffer(char ch)
{
- if(in_buf_used >= maxlen_inbuf-1)
+ if(in_buf_used >= max_usermsg_len-1)
return;
in_buffer[in_buf_used] = ch;
diff --git a/src/client/user.hpp b/src/client/user.hpp
index 03afb87..8e2218a 100644
--- a/src/client/user.hpp
+++ b/src/client/user.hpp
@@ -4,25 +4,24 @@
#include "clui.hpp"
#include "../const_vars.hpp"
-const int maxlen_inbuf = max_line_len + max_name_len + 1;
-const int maxlen_outbuf = max_line_len + 1;
-
class Client {
int fd;
- char in_buffer[maxlen_inbuf]; // for input
+ char in_buffer[max_usermsg_len]; // for input
int in_buf_used;
- char out_buffer[maxlen_outbuf]; // for message
+ 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) { }
+ : fd(i_fd), in_buf_used(0), out_buf_used(0) { }
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);