diff --git a/Makefile.am b/Makefile.am index dceb81f..ed1c003 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,4 +11,6 @@ SilverMUDServer_SOURCES = \ SilverMUDClient_SOURCES = \ source/messages.c \ + source/client/client-drawing.c \ + source/client/receiving-thread.c \ source/client/main.c diff --git a/source/client/client-drawing.c b/source/client/client-drawing.c new file mode 100644 index 0000000..faa21da --- /dev/null +++ b/source/client/client-drawing.c @@ -0,0 +1,61 @@ +// ========================================== +// | SilverMUD Client - client-drawing.c | +// | Copyright (C) 2023, Barra Ó Catháin | +// | See end of file for copyright notice. | +// ========================================== +#include "../config.h" +#include "client-drawing.h" + +void redrawClientLayout(WINDOW * gameWindow, WINDOW * chatWindow, WINDOW * inputWindow) +{ + int height, width; + getmaxyx(stdscr, height, width); + + // Draw the lines that will seperate windows: + wborder(stdscr, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); + attron(A_REVERSE); + mvwhline(stdscr, 0, 0, '=', width); + mvwhline(stdscr, height / 2, 0, '=', width); + mvwhline(stdscr, height - 2, 0, '=', width); + + // Write the labels for windows: + attron(COLOR_PAIR(1)); + mvwprintw(stdscr, 0, 1, " SilverMUD | Version %s ", PACKAGE_VERSION); + mvwprintw(stdscr, height / 2, 1, " Chat "); + mvwprintw(stdscr, height - 2, 1, " Input "); + attroff(COLOR_PAIR(1)); + attroff(A_REVERSE); + + // Move the windows into place: + mvwin(gameWindow, 1, 1); + mvwin(chatWindow, (height / 2) + 1 , 1); + mvwin(inputWindow, height - 1, 1); + + // Resize the windows: + wresize(gameWindow, (height - 2) / 2, width - 2); + wresize(chatWindow, ((height - 4) / 2) - (1 - (height % 2)), width - 2); + wresize(inputWindow, 1, width - 2); + + // Refresh every window: + wrefresh(stdscr); + wrefresh(gameWindow); + wrefresh(chatWindow); + wrefresh(inputWindow); +} + +// ======================================================== +// | End of client-drawing.c, copyright notice follows. | +// ======================================================== + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . diff --git a/source/client/client-drawing.h b/source/client/client-drawing.h new file mode 100644 index 0000000..dd7a4d4 --- /dev/null +++ b/source/client/client-drawing.h @@ -0,0 +1,28 @@ +// ========================================== +// | SilverMUD Client - client-drawing.h | +// | Copyright (C) 2023, Barra Ó Catháin | +// | See end of file for copyright notice. | +// ========================================== +#ifndef CLIENT_DRAWING_H +#define CLIENT_DRAWING_H +#include + +void redrawClientLayout(WINDOW * gameWindow, WINDOW * chatWindow, WINDOW * inputWindow); + +#endif +// ======================================================== +// | End of client-drawing.h, copyright notice follows. | +// ======================================================== + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . diff --git a/source/client/main.c b/source/client/main.c index 40ca09b..6b9821c 100644 --- a/source/client/main.c +++ b/source/client/main.c @@ -15,6 +15,8 @@ #include "../config.h" #include "../messages.h" +#include "client-drawing.h" +#include "receiving-thread.h" int main (int argc, char ** argv) { @@ -79,62 +81,44 @@ int main (int argc, char ** argv) // Enable colours: start_color(); use_default_colors(); - init_pair(1, COLOR_GREEN, -1); - + init_pair(1, COLOR_GREEN, -1); + init_pair(2, COLOR_YELLOW, -1); + init_pair(3, COLOR_RED, -1); + init_pair(4, COLOR_BLUE, -1); + init_pair(5, COLOR_CYAN, -1); + init_pair(6, COLOR_MAGENTA, -1); + // Variables needed for the main loop: int height, width; getmaxyx(stdscr, height, width); struct ClientToServerMessage message; - WINDOW * chatWindow, * gameWindow; + WINDOW * chatWindow, * gameWindow, * inputWindow; + inputWindow = newwin(1, width - 2, height - 1, 1); gameWindow = newwin((height / 2) - 1, width - 2, 1, 1); chatWindow = newwin((height / 2) - 3, width - 2, (height / 2) + 1, 1); scrollok(gameWindow, TRUE); scrollok(chatWindow, TRUE); + scrollok(inputWindow, TRUE); + + redrawClientLayout(gameWindow, chatWindow, inputWindow); + + struct ReceivingThreadArguments receivingThreadArguments; + receivingThreadArguments.chatWindow = chatWindow; + receivingThreadArguments.gameWindow = gameWindow; + receivingThreadArguments.inputWindow = inputWindow; + receivingThreadArguments.session = tlsSession; + + pthread_t receivingThread; + pthread_create(&receivingThread, NULL, receivingThreadHandler, &receivingThreadArguments); while (true) - { - // Store the current size of the terminal: - getmaxyx(stdscr, height, width); + { + wgetnstr(inputWindow, message.content, 1024); - - // Draw the lines that will seperate windows: - wborder(stdscr, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); - mvwhline(stdscr, 0, 0, '=', width); - mvwhline(stdscr, height / 2, 0, '=', width); - mvwhline(stdscr, height - 2, 0, '=', width); - - // Write the labels for windows: - attron(COLOR_PAIR(1)); - mvwprintw(stdscr, 0, 1, " SilverMUD | Version %s ", PACKAGE_VERSION); - mvwprintw(stdscr, height / 2, 1, " Chat "); - mvwprintw(stdscr, height - 2, 1, " Input "); - attroff(COLOR_PAIR(1)); - - wrefresh(stdscr); - - // Move the windows into place: - mvwin(gameWindow, 1, 1); - mvwin(chatWindow, (height / 2) + 1 , 1); - wresize(gameWindow, (height - 2) / 2, width - 2); - wresize(chatWindow, ((height - 3) / 2) - (1 - (height % 2)), width - 2); - - wrefresh(gameWindow); - wrefresh(chatWindow); - - // Move to the input area: - wmove(stdscr, height - 1, 1); - wgetnstr(stdscr, message.content, 1024); - - // Clear the input area: - wmove(stdscr, height - 2, 1); - clrtoeol(); - if (message.content[0] != '\0') { - wprintw(gameWindow, "\n%s", message.content); - wprintw(chatWindow, "\n%s", message.content); gnutls_record_send(tlsSession, &message, 1024); } } diff --git a/source/client/receiving-thread.c b/source/client/receiving-thread.c new file mode 100644 index 0000000..eeebe02 --- /dev/null +++ b/source/client/receiving-thread.c @@ -0,0 +1,63 @@ +// ========================================== +// | SilverMUD Client - receiving-thread.c | +// | Copyright (C) 2023, Barra Ó Catháin | +// | See end of file for copyright notice. | +// ========================================== +#include +#include + +#include "../messages.h" +#include "client-drawing.h" +#include "receiving-thread.h" + +void * receivingThreadHandler(void * threadArguments) +{ + start_color(); + use_default_colors(); + init_pair(1, COLOR_GREEN, -1); + init_pair(2, COLOR_YELLOW, -1); + init_pair(3, COLOR_RED, -1); + init_pair(4, COLOR_BLUE, -1); + init_pair(5, COLOR_CYAN, -1); + init_pair(6, COLOR_MAGENTA, -1); + + // Unpack the thread's arguments: + gnutls_session_t session = ((struct ReceivingThreadArguments *)threadArguments)->session; + WINDOW * chatWindow = ((struct ReceivingThreadArguments *)threadArguments)->chatWindow, + * gameWindow = ((struct ReceivingThreadArguments *)threadArguments)->gameWindow, + * inputWindow = ((struct ReceivingThreadArguments *)threadArguments)->inputWindow; + + // Print a message into the game window: + wprintw(gameWindow, "Connection successful. Welcome to "); + wattrset(gameWindow, COLOR_PAIR(2)); + wprintw(gameWindow, "SilverMUD!\n"); + wattrset(gameWindow, A_NORMAL); + + struct ServerToClientMessage currentMessage; + while (true) + { + gnutls_record_recv(session, ¤tMessage, sizeof(struct ServerToClientMessage)); + wattrset(chatWindow, A_BOLD); + wprintw(chatWindow, "<%s>: ", currentMessage.name); + wattrset(chatWindow, A_NORMAL); + wprintw(chatWindow, "%s\n", currentMessage.content); + redrawClientLayout(gameWindow, chatWindow, inputWindow); + } +} + +// ======================================================== +// | End of receiving-thread.c, copyright notice follows. | +// ======================================================== + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . diff --git a/source/client/receiving-thread.h b/source/client/receiving-thread.h new file mode 100644 index 0000000..69a4c77 --- /dev/null +++ b/source/client/receiving-thread.h @@ -0,0 +1,35 @@ +// ========================================== +// | SilverMUD Client - receiving-thread.h | +// | Copyright (C) 2023, Barra Ó Catháin | +// | See end of file for copyright notice. | +// ========================================== +#ifndef RECEIVING_THREAD_H +#define RECEIVING_THREAD_H +#include +#include + +struct ReceivingThreadArguments +{ + WINDOW * chatWindow, * gameWindow, * inputWindow; + gnutls_session_t session; +}; + +void * receivingThreadHandler(void * threadArguments); + +#endif +// ======================================================== +// | End of receiving-thread.h, copyright notice follows. | +// ======================================================== + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . diff --git a/source/server/main.c b/source/server/main.c index b1183f5..a256dc2 100644 --- a/source/server/main.c +++ b/source/server/main.c @@ -184,8 +184,22 @@ int main (int argc, char ** argv) } else if (returnValue == sizeof(struct ClientToServerMessage)) { - printf("%s\n", message.content); - fflush(stdout); + struct ServerToClientMessage outputMessage; + + // Copy the message to the output format: + outputMessage.type = LOCAL_CHAT; + sprintf(outputMessage.name, "UNNAMED"); + strncpy(outputMessage.content, message.content, MESSAGE_CONTENT_LENGTH); + + struct ClientConnectionNode * currentClient = clientConnections.head; + while (currentClient != NULL) + { + gnutls_record_send(*currentClient->connection->tlsSession, &outputMessage, + sizeof(struct ServerToClientMessage)); + currentClient = currentClient->next; + } + // printf("%s\n", message.content); + // fflush(stdout); } } else