Alpha 0.2 release of SilverMUD:
Features Added: - Two window messaging in the client. - Input sanitization to prevent server spam. - Slow print text effect ported to Ncurses. - Graceful handling of C-c. Features Changed: - Ncurses is now used in place of raw-terminal output. - Sending and Receiving are now on their own threads. - Makefile updated to add server linking variable. - Control characters no longer cause server spam. - Splash texts' version incremented. - Makefile updated to link Ncurses. Features Removed: - None. Squashed commit of the following: commit9411803942
Author: Barry Kane <bazzakane@gmail.com> Date: Fri Sep 10 15:07:42 2021 +0100 Increment version message for merge. Incremented the version number by 0.1 for the server. Added version splash to the client. commit7047d0ee08
Author: Barry Kane <bazzakane@gmail.com> Date: Fri Sep 10 15:03:02 2021 +0100 Added two-window messaging to the client. Client now has two seperate Ncurses windows for sending and receiving. Added SIGINT handler which sets a global boolean to gracefully exit and free memory. Sending and Receiving are now on their own threads. A pointer-to-struct is now passed to the threads. The main thread will now wait to cancel the threads upon receiving SIGINT. slowPrintNcurses now takes a window argument. The server now doesn't check that a client receives the message that they sent, allowing for full chat history. commit33bc9bcda0
Author: Barry Kane <bazzakane@gmail.com> Date: Fri Sep 3 18:47:11 2021 +0100 Adapted client to use Ncurses instead of raw terminal output: Created "slowPrintNcurses", which is a version of "slowPrint" compatible with Ncurses screens. Ncurses is now used in place of raw-terminal output. The screen clears after inital start-up messages. C-d no longer exits, and still doesn't spam. Added Ncurses to the ld options of client in the Makefile. Created ld options for server in the Makefile. commit849a80bd37
Author: Barry Kane <barry@omnimenu.ie> Date: Thu Aug 19 23:07:58 2021 +0100 Basic input sanatization: Created new library to deal with user input. Implemented check in client to prevent C-d spamming the server. C-d now exits. Implemented check in client to prevent clients sending messages containing only newlines to the server. commit2c093903a4
Author: Barry Kane <barry@omnimenu.ie> Date: Tue Aug 17 18:57:56 2021 +0100 Git Sanity Check
This commit is contained in:
parent
618b2144e3
commit
b9d5c36683
7
Makefile
7
Makefile
|
@ -1,16 +1,17 @@
|
|||
CC = gcc
|
||||
clientsrc = $(wildcard src/misc/*.c) \
|
||||
src/SilverMUDClient.c
|
||||
clientobj = $(clientsrc:.c=.o)
|
||||
serversrc = $(wildcard src/misc/*.c) \
|
||||
src/SilverMUDServer.c
|
||||
serverobj = $(serversrc:.c=.o)
|
||||
CLIENTLDFLAGS= -lpthread
|
||||
|
||||
CLIENTLDFLAGS= -lpthread -lncurses
|
||||
SERVERLDFLAGS= -lncurses
|
||||
SilverMUDClient: $(clientobj)
|
||||
gcc -o $@ $^ $(CLIENTLDFLAGS)
|
||||
|
||||
SilverMUDServer: $(serverobj)
|
||||
gcc -o $@ $^
|
||||
gcc -o $@ $^ $(SERVERLDFLAGS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
|
|
@ -3,50 +3,87 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include <ncurses.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include "misc/texteffects.h"
|
||||
#include "misc/inputhandling.h"
|
||||
#define MAX 1024
|
||||
#define PORT 5000
|
||||
#define SA struct sockaddr
|
||||
|
||||
void * messageSender(void * sockfd)
|
||||
// A struct for passing arguments to our threads containing a file descriptor and a window pointer:
|
||||
typedef struct threadparameters
|
||||
{
|
||||
int socketDescriptor;
|
||||
WINDOW * window;
|
||||
} threadparameters;
|
||||
|
||||
// A globally availible exit boolean.
|
||||
bool shouldExit = false;
|
||||
|
||||
void sigintHandler(int signal)
|
||||
{
|
||||
shouldExit = true;
|
||||
}
|
||||
|
||||
void * messageSender(void * parameters)
|
||||
{
|
||||
// Takes user input in a window, sanatizes it, and sends it to the server:
|
||||
struct threadparameters *threadParameters = parameters;
|
||||
char sendBuffer[MAX];
|
||||
int characterindex;
|
||||
|
||||
while (1)
|
||||
|
||||
while (!shouldExit)
|
||||
{
|
||||
bzero(sendBuffer, MAX);
|
||||
printf("COMM-LINK> ");
|
||||
fgets(sendBuffer, MAX, stdin);
|
||||
if(sendBuffer[0] != '\n');
|
||||
wprintw(threadParameters->window, "\n\n\nCOMM-LINK> ");
|
||||
if(wgetnstr(threadParameters->window, sendBuffer, MAX) == ERR)
|
||||
{
|
||||
write((long)sockfd, sendBuffer, MAX);
|
||||
// Quit if there's any funny business with getting input:
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
userInputSanatize(sendBuffer, MAX);
|
||||
if(sendBuffer[0] == '\n')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
write(threadParameters->socketDescriptor, sendBuffer, MAX);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
void * messageReceiver(void * sockfd)
|
||||
void * messageReceiver(void * parameters)
|
||||
{
|
||||
// Takes messages from the server and prints them to the chat log window:
|
||||
struct threadparameters *threadParameters = parameters;
|
||||
char receiveBuffer[MAX];
|
||||
while (1)
|
||||
while (!shouldExit)
|
||||
{
|
||||
read((long)sockfd, receiveBuffer, MAX);
|
||||
slowprint("\nUSER-MESSAGE: ", 8000);
|
||||
slowprint(receiveBuffer, 8000);
|
||||
slowprint("\nCOMM-LINK (CONT.)> ", 8000);
|
||||
read(threadParameters->socketDescriptor, receiveBuffer, MAX);
|
||||
slowPrintNcurses("USER-MESSAGE: ", 8000, threadParameters->window);
|
||||
slowPrintNcurses(receiveBuffer, 8000, threadParameters->window);
|
||||
bzero(receiveBuffer, MAX);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int sockfd, connfd;
|
||||
struct sockaddr_in servaddr, cli;
|
||||
pthread_t messagingThread;
|
||||
pthread_t sendingThread;
|
||||
pthread_t receivingThread;
|
||||
|
||||
// Set the SIGINT handler.
|
||||
signal(SIGINT, sigintHandler);
|
||||
|
||||
// Print welcome message:
|
||||
slowPrint("\n--==== \033[33;40mSILVERKIN INDUSTRIES\033[0m COMM-LINK CLIENT ====--\nVersion Alpha 0.2\n", 5000);
|
||||
|
||||
// Give me a socket, and make sure it's working:
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
@ -57,7 +94,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
slowprint("Socket successfully created.\n", 8000);
|
||||
slowPrint("Socket successfully created.\n", 8000);
|
||||
}
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
|
||||
|
@ -76,18 +113,59 @@ int main(int argc, char **argv)
|
|||
// Connect the server and client sockets, Kronk:
|
||||
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0)
|
||||
{
|
||||
slowprint("Connection with the Silverkin Industries Comm-Link Server Failed:\nPlease contact your service representative.\n", 8000);
|
||||
slowPrint("Connection with the Silverkin Industries Comm-Link Server Failed:\nPlease contact your service representative.\n", 8000);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
slowprint("Connected to the Silverkin Industries Comm-Link Server:\nHave a pleasant day.\n", 8000);
|
||||
slowPrint("Connected to the Silverkin Industries Comm-Link Server:\nHave a pleasant day.\n", 8000);
|
||||
}
|
||||
usleep(100000);
|
||||
|
||||
// Run a thread to send messages, and use main to recieve.
|
||||
pthread_create(&messagingThread, NULL, messageSender, (void *)(long)sockfd);
|
||||
messageReceiver((void *)(long)sockfd);
|
||||
// Setup Ncurses:
|
||||
initscr();
|
||||
|
||||
// Create two pointers to structs to pass arguments to the threads:
|
||||
threadparameters * logArea;
|
||||
threadparameters * messageArea;
|
||||
|
||||
// Close the socket.
|
||||
logArea = malloc(sizeof(*logArea));
|
||||
messageArea = malloc(sizeof(*messageArea));
|
||||
|
||||
// Make the windows for the structs, and pass the socket descriptor:
|
||||
logArea->window = newwin(LINES - 5, COLS - 2, 1, 1);
|
||||
logArea->socketDescriptor = sockfd;
|
||||
messageArea->window = newwin(3, COLS, LINES - 3, 0);
|
||||
messageArea->socketDescriptor = sockfd;
|
||||
|
||||
// Set the two windows to scroll:
|
||||
scrollok(logArea->window, true);
|
||||
scrollok(messageArea->window, true);
|
||||
|
||||
// Run a thread to send messages, and use main to recieve:
|
||||
pthread_create(&sendingThread, NULL, messageSender, messageArea);
|
||||
pthread_create(&receivingThread, NULL, messageReceiver, logArea);
|
||||
|
||||
// Wait for SIGINT to change
|
||||
while(!shouldExit)
|
||||
{
|
||||
sleep(250);
|
||||
}
|
||||
|
||||
// Close the threads:
|
||||
pthread_cancel(sendingThread);
|
||||
pthread_cancel(receivingThread);
|
||||
|
||||
// Close the socket:
|
||||
close(sockfd);
|
||||
|
||||
// Free the structs:
|
||||
free(logArea);
|
||||
free(messageArea);
|
||||
|
||||
// Unsetup Ncurses:
|
||||
endwin();
|
||||
|
||||
// Say Goodbye:
|
||||
slowPrint("\nThank you for choosing Silverkin Industries, valued customer!\n", 8000);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ncurses.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -27,8 +28,8 @@ int main()
|
|||
struct sockaddr_in serverAddress, clientAddress;
|
||||
|
||||
// Give an intro: Display the Silverkin Industries logo and splash text.
|
||||
slowprint(logostring, 3000);
|
||||
slowprint("\n--==== \033[33;40mSILVERKIN INDUSTRIES\033[0m COMM-LINK SERVER ====--\nVersion Alpha 0.1\n", 5000);
|
||||
slowPrint(logostring, 3000);
|
||||
slowPrint("\n--==== \033[33;40mSILVERKIN INDUSTRIES\033[0m COMM-LINK SERVER ====--\nVersion Alpha 0.2\n", 5000);
|
||||
|
||||
// Initialize the sockets to 0, so we don't crash.
|
||||
for (int index = 0; index < maxClients; index++)
|
||||
|
@ -46,7 +47,7 @@ int main()
|
|||
|
||||
else
|
||||
{
|
||||
slowprint(" Socket creation is \033[32;40mGREEN.\033[0m\n", 5000);
|
||||
slowPrint(" Socket creation is \033[32;40mGREEN.\033[0m\n", 5000);
|
||||
}
|
||||
|
||||
bzero(&serverAddress, sizeof(serverAddress));
|
||||
|
@ -64,7 +65,7 @@ int main()
|
|||
}
|
||||
else
|
||||
{
|
||||
slowprint(" Socket binding is \033[32;40mGREEN.\033[0m\n", 5000);
|
||||
slowPrint(" Socket binding is \033[32;40mGREEN.\033[0m\n", 5000);
|
||||
}
|
||||
|
||||
// Let's start listening:
|
||||
|
@ -75,7 +76,7 @@ int main()
|
|||
}
|
||||
else
|
||||
{
|
||||
slowprint(" Server listening is \033[32;40mGREEN.\033[0m\n", 5000);
|
||||
slowPrint(" Server listening is \033[32;40mGREEN.\033[0m\n", 5000);
|
||||
}
|
||||
length = sizeof(clientAddress);
|
||||
|
||||
|
@ -171,7 +172,7 @@ int main()
|
|||
fflush(stdout);
|
||||
for (int sendIndex = 0; sendIndex < clientsAmount; sendIndex++)
|
||||
{
|
||||
if(sendIndex != i && clientSockets[sendIndex] != STDIN_FILENO && clientSockets[sendIndex] != STDOUT_FILENO && clientSockets[sendIndex] != STDERR_FILENO)
|
||||
if(clientSockets[sendIndex] != STDIN_FILENO && clientSockets[sendIndex] != STDOUT_FILENO && clientSockets[sendIndex] != STDERR_FILENO)
|
||||
{
|
||||
write(clientSockets[sendIndex], receiveBuffer, sizeof(receiveBuffer));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// inputhandling.c: Implementation of input handling library for SilverMUD.
|
||||
// Barry Kane, 2021.
|
||||
#include <ctype.h>
|
||||
|
||||
void userInputSanatize(char * inputString, int length)
|
||||
{
|
||||
for(int index = 0; index <= length; index++)
|
||||
{
|
||||
if(!isprint(inputString[index]))
|
||||
{
|
||||
inputString[index] = '\n';
|
||||
inputString[index + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// inputhandling.h: Header file for the inputhandling library for SilverMUD.
|
||||
// Barry Kane, 2021
|
||||
#ifndef INPUTHANDLING_H
|
||||
#define INPUTHANDLING_H
|
||||
#include <ctype.h>
|
||||
|
||||
// Sanatize user input to ensure it's okay to send to the server:
|
||||
void userInputSanatize(char * inputString, int length);
|
||||
|
||||
#endif
|
|
@ -2,8 +2,9 @@
|
|||
// Barry Kane, 2021.
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
void slowprint(char * stringToPrint, int delay)
|
||||
void slowPrint(char * stringToPrint, int delay)
|
||||
{
|
||||
int characterIndex = 0;
|
||||
while(stringToPrint[characterIndex] != '\0')
|
||||
|
@ -15,3 +16,17 @@ void slowprint(char * stringToPrint, int delay)
|
|||
characterIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
void slowPrintNcurses(char * stringToPrint, int delay, WINDOW * window)
|
||||
{
|
||||
int characterIndex = 0;
|
||||
while(stringToPrint[characterIndex] != '\0')
|
||||
{
|
||||
waddch(window, stringToPrint[characterIndex]);
|
||||
// Refresh the ncurses screen.
|
||||
wrefresh(window);
|
||||
usleep(delay);
|
||||
characterIndex++;
|
||||
}
|
||||
wrefresh(window);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
// texteffects.h: Header file for the texteffects library for SilverMUD.
|
||||
// Barry Kane, 2021.
|
||||
#ifndef TEXTEFFECTS_H_
|
||||
#define TEXTEFFECTS_H_
|
||||
#include <stdio.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
// A fancy, character by character print. Similar to a serial terminal with lower baud rate.
|
||||
void slowprint(char * stringToPrint, int delay);
|
||||
void slowPrint(char * stringToPrint, int delay);
|
||||
|
||||
// The same, altered to work with Ncurses.
|
||||
void slowPrintNcurses(char * stringToPrint, int delay, WINDOW * window);
|
||||
|
||||
// A string containing an ASCII art version of the Silverkin Industries logo.
|
||||
char * logostring = " ///////\n //////////////////////////////////////////\n ///////////////////////////////////////////////////////////\n ////////// ////////////////////////////\n ### # # # # ##### ### # # # # # /////////////////\n ### # # # # ## # # ## # ## # //////////////\n ## # # # # # ### # # # # # # /////////\n #### # ### # ##### # # # # # # ## ///////\n # ## # ##### # # ### ### ### # ##### ### ////// \n # # # # # # # # ## # # # # ## ## ////\n # # # # # # # # ## # ### # # ## //\n # # ### ##### ##### ### # # # # #### ### //\n";
|
||||
|
|
Loading…
Reference in New Issue