From 5a53e9f1974598c62602b3b812398884906b8d00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barra=20=C3=93=20Cath=C3=A1in?= Date: Sun, 10 Sep 2023 17:24:46 +0100 Subject: [PATCH] Added basic player type containing a name, and made the server echo messages with player name. --- Makefile.am | 5 ++-- configure.ac | 1 + notes/SilverMUD-Implementation.org | 2 +- source/server/connections.c | 8 +++--- source/server/connections.h | 6 ++--- source/server/main.c | 30 ++++++++++++++++------ source/server/player-data.c | 40 ++++++++++++++++++++++++++++++ source/server/player-data.h | 38 ++++++++++++++++++++++++++++ 8 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 source/server/player-data.c create mode 100644 source/server/player-data.h diff --git a/Makefile.am b/Makefile.am index ed1c003..6f59a34 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,11 @@ bin_PROGRAMS = SilverMUDServer SilverMUDClient dist_doc_DATA = README.org -SilverMUDServer_CFLAGS = -I/usr/include/guile/3.0 -I/usr -lguile-3.0 -lgc -lpthread -ldl -lgnutls -g -SilverMUDClient_CFLAGS = -I/usr/include/guile/3.0 -I/usr -lguile-3.0 -lgc -lpthread -ldl -lgnutls -g -lncurses +SilverMUDServer_CFLAGS = -lgnutls -g $(GUILE_CFLAGS) $(GUILE_LIBS) +SilverMUDClient_CFLAGS = -lgnutls -g -lncurses $(GUILE_CFLAGS) $(GUILE_LIBS) SilverMUDServer_SOURCES = \ source/messages.c \ + source/server/player-data.c \ source/server/connections.c \ source/server/scheme-integration.c \ source/server/main.c diff --git a/configure.ac b/configure.ac index 8c0f855..1151bc2 100644 --- a/configure.ac +++ b/configure.ac @@ -5,4 +5,5 @@ AC_CONFIG_HEADERS([source/config.h]) AC_CONFIG_FILES([ Makefile ]) +PKG_CHECK_MODULES([GUILE], [guile-3.0]) AC_OUTPUT diff --git a/notes/SilverMUD-Implementation.org b/notes/SilverMUD-Implementation.org index 88b1d7d..bec3dfb 100644 --- a/notes/SilverMUD-Implementation.org +++ b/notes/SilverMUD-Implementation.org @@ -1,4 +1,4 @@ -#+TITLE: SilverMUD Design Document +#+TITLE: SilverMUD Implementation Document This document contains information about various implementation details of SilverMUD, as a scratchpad for decisions before implementation. diff --git a/source/server/connections.c b/source/server/connections.c index 77ee0a4..33bc100 100644 --- a/source/server/connections.c +++ b/source/server/connections.c @@ -121,7 +121,7 @@ int removeConnectionByFileDescriptor(struct ClientConnectionList * list, int fil return 0; } -int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnutls_session_t * tlsSession) +struct ClientConnection * addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnutls_session_t * tlsSession) { // Allocate memory for the structures: struct ClientConnectionNode * newConnectionNode = calloc(1, sizeof(struct ClientConnectionNode)); @@ -141,7 +141,7 @@ int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnu list->clientCount++; - return 0; + return newConnectionNode->connection; } // Insert it in the appropriate place in the list: @@ -161,7 +161,7 @@ int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnu list->clientCount++; - return 0; + return newConnectionNode->connection; } else { @@ -183,7 +183,7 @@ int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnu } list->clientCount++; - return 0; + return newConnectionNode->connection; } } diff --git a/source/server/connections.h b/source/server/connections.h index 943d9d0..4ba77c9 100644 --- a/source/server/connections.h +++ b/source/server/connections.h @@ -9,9 +9,9 @@ #include struct ClientConnection -{ - // TODO: Pointer to player struct. +{ gnutls_session_t * tlsSession; + struct Player * player; int fileDescriptor; }; @@ -35,7 +35,7 @@ struct ClientConnection * findConnectionByFileDescriptor(struct ClientConnection struct ClientConnection * findConnectionByTlsSession(struct ClientConnectionList * list, gnutls_session_t * tlsSession); int removeConnectionByFileDescriptor(struct ClientConnectionList * list, int fileDescriptor); -int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnutls_session_t * tlsSession); +struct ClientConnection * addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnutls_session_t * tlsSession); #endif // =================================================== diff --git a/source/server/main.c b/source/server/main.c index a256dc2..c2549aa 100644 --- a/source/server/main.c +++ b/source/server/main.c @@ -19,6 +19,7 @@ #include #include +#include "player-data.h" #include "connections.h" #include "../messages.h" #include "scheme-integration.h" @@ -159,7 +160,9 @@ int main (int argc, char ** argv) epoll_ctl(connectedClients, EPOLL_CTL_ADD, newSocket, &watchedEvents); // Add the connection to the list: - addNewConnection(&clientConnections, newSocket, tlsSession); + struct ClientConnection * newConnection = addNewConnection(&clientConnections, newSocket, tlsSession); + newConnection->player = createNewPlayer(newConnection); + sprintf(newConnection->player->name, "Player %02d", clientConnections.clientCount); // Print a message: printf("New connection established. %d client(s), session ID %u.\n", @@ -171,8 +174,10 @@ int main (int argc, char ** argv) struct ClientConnection * connection = findConnectionByFileDescriptor(&clientConnections, events[index].data.fd); if (connection != NULL) { - struct ClientToServerMessage message; - int returnValue = gnutls_record_recv(*connection->tlsSession, &message, sizeof(struct ClientToServerMessage)); + // Read the data from the TLS session: + struct ClientToServerMessage message; + int returnValue = gnutls_record_recv(*connection->tlsSession, &message, sizeof(struct ClientToServerMessage)); + if (returnValue == 0 || returnValue == -10) { printf("Closing session ID: %u.\n", *connection->tlsSession); @@ -180,6 +185,7 @@ int main (int argc, char ** argv) gnutls_bye(*connection->tlsSession, 2); shutdown(connection->fileDescriptor, 2); close(connection->fileDescriptor); + deallocatePlayer(&connection->player); removeConnectionByFileDescriptor(&clientConnections, connection->fileDescriptor); } else if (returnValue == sizeof(struct ClientToServerMessage)) @@ -188,18 +194,26 @@ int main (int argc, char ** argv) // Copy the message to the output format: outputMessage.type = LOCAL_CHAT; - sprintf(outputMessage.name, "UNNAMED"); + + if (connection->player != NULL) + { + strncpy(outputMessage.name, connection->player->name, 64); + } + else + { + sprintf(outputMessage.name, "UNNAMED"); + } + strncpy(outputMessage.content, message.content, MESSAGE_CONTENT_LENGTH); + // Echo the message into all other clients: (Temporary) 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 @@ -216,7 +230,7 @@ int main (int argc, char ** argv) } // Wait for all other threads to terminate: - //pthread_join(schemeREPLThread, NULL); + //pthread_join(schemeREPLThread, NULL); // Return a successful status code to the operating system: return 0; diff --git a/source/server/player-data.c b/source/server/player-data.c new file mode 100644 index 0000000..a304b87 --- /dev/null +++ b/source/server/player-data.c @@ -0,0 +1,40 @@ +// ========================================= +// | SilverMUD Server - player-data.c | +// | Copyright (C) 2023, Barra Ó Catháin | +// | See end of file for copyright notice. | +// ========================================= +#include +#include "player-data.h" + +// Allocates and sets up a new player according to the world's starter character sheet: +struct Player * createNewPlayer(struct ClientConnection * connection) +{ + struct Player * newPlayer = calloc(1, sizeof(struct Player)); + newPlayer->connection = connection; + + return newPlayer; +} + +// Deallocates a player: +void deallocatePlayer(struct Player ** player) +{ + free(*player); + *player = NULL; +} + +// =================================================== +// | End of player-data.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/server/player-data.h b/source/server/player-data.h new file mode 100644 index 0000000..46998d2 --- /dev/null +++ b/source/server/player-data.h @@ -0,0 +1,38 @@ +// ========================================= +// | SilverMUD Server - player-data.h | +// | Copyright (C) 2023, Barra Ó Catháin | +// | See end of file for copyright notice. | +// ========================================= +#ifndef PLAYER_DATA_H +#define PLAYER_DATA_H +#include "connections.h" + +struct Player +{ + struct ClientConnection * connection; + char name[64]; +}; + +// Allocates and sets up a new player according to the world's starter character sheet: +struct Player * createNewPlayer(struct ClientConnection * connection); + +// Deallocates a player: +void deallocatePlayer(struct Player ** player); + +#endif +// =================================================== +// | End of player-data.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 .