Added basic player type containing a name, and made the server echo messages with player name.

This commit is contained in:
Barra Ó Catháin 2023-09-10 17:24:46 +01:00
parent 3fc75ef30f
commit 5a53e9f197
8 changed files with 112 additions and 18 deletions

View File

@ -1,10 +1,11 @@
bin_PROGRAMS = SilverMUDServer SilverMUDClient bin_PROGRAMS = SilverMUDServer SilverMUDClient
dist_doc_DATA = README.org dist_doc_DATA = README.org
SilverMUDServer_CFLAGS = -I/usr/include/guile/3.0 -I/usr -lguile-3.0 -lgc -lpthread -ldl -lgnutls -g SilverMUDServer_CFLAGS = -lgnutls -g $(GUILE_CFLAGS) $(GUILE_LIBS)
SilverMUDClient_CFLAGS = -I/usr/include/guile/3.0 -I/usr -lguile-3.0 -lgc -lpthread -ldl -lgnutls -g -lncurses SilverMUDClient_CFLAGS = -lgnutls -g -lncurses $(GUILE_CFLAGS) $(GUILE_LIBS)
SilverMUDServer_SOURCES = \ SilverMUDServer_SOURCES = \
source/messages.c \ source/messages.c \
source/server/player-data.c \
source/server/connections.c \ source/server/connections.c \
source/server/scheme-integration.c \ source/server/scheme-integration.c \
source/server/main.c source/server/main.c

View File

@ -5,4 +5,5 @@ AC_CONFIG_HEADERS([source/config.h])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
]) ])
PKG_CHECK_MODULES([GUILE], [guile-3.0])
AC_OUTPUT AC_OUTPUT

View File

@ -1,4 +1,4 @@
#+TITLE: SilverMUD Design Document #+TITLE: SilverMUD Implementation Document
This document contains information about various implementation details of This document contains information about various implementation details of
SilverMUD, as a scratchpad for decisions before implementation. SilverMUD, as a scratchpad for decisions before implementation.

View File

@ -121,7 +121,7 @@ int removeConnectionByFileDescriptor(struct ClientConnectionList * list, int fil
return 0; 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: // Allocate memory for the structures:
struct ClientConnectionNode * newConnectionNode = calloc(1, sizeof(struct ClientConnectionNode)); struct ClientConnectionNode * newConnectionNode = calloc(1, sizeof(struct ClientConnectionNode));
@ -141,7 +141,7 @@ int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnu
list->clientCount++; list->clientCount++;
return 0; return newConnectionNode->connection;
} }
// Insert it in the appropriate place in the list: // Insert it in the appropriate place in the list:
@ -161,7 +161,7 @@ int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnu
list->clientCount++; list->clientCount++;
return 0; return newConnectionNode->connection;
} }
else else
{ {
@ -183,7 +183,7 @@ int addNewConnection(struct ClientConnectionList * list, int fileDescriptor, gnu
} }
list->clientCount++; list->clientCount++;
return 0; return newConnectionNode->connection;
} }
} }

View File

@ -9,9 +9,9 @@
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
struct ClientConnection struct ClientConnection
{ {
// TODO: Pointer to player struct.
gnutls_session_t * tlsSession; gnutls_session_t * tlsSession;
struct Player * player;
int fileDescriptor; int fileDescriptor;
}; };
@ -35,7 +35,7 @@ struct ClientConnection * findConnectionByFileDescriptor(struct ClientConnection
struct ClientConnection * findConnectionByTlsSession(struct ClientConnectionList * list, gnutls_session_t * tlsSession); struct ClientConnection * findConnectionByTlsSession(struct ClientConnectionList * list, gnutls_session_t * tlsSession);
int removeConnectionByFileDescriptor(struct ClientConnectionList * list, int fileDescriptor); 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 #endif
// =================================================== // ===================================================

View File

@ -19,6 +19,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#include "player-data.h"
#include "connections.h" #include "connections.h"
#include "../messages.h" #include "../messages.h"
#include "scheme-integration.h" #include "scheme-integration.h"
@ -159,7 +160,9 @@ int main (int argc, char ** argv)
epoll_ctl(connectedClients, EPOLL_CTL_ADD, newSocket, &watchedEvents); epoll_ctl(connectedClients, EPOLL_CTL_ADD, newSocket, &watchedEvents);
// Add the connection to the list: // 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: // Print a message:
printf("New connection established. %d client(s), session ID %u.\n", 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); struct ClientConnection * connection = findConnectionByFileDescriptor(&clientConnections, events[index].data.fd);
if (connection != NULL) if (connection != NULL)
{ {
struct ClientToServerMessage message; // Read the data from the TLS session:
int returnValue = gnutls_record_recv(*connection->tlsSession, &message, sizeof(struct ClientToServerMessage)); struct ClientToServerMessage message;
int returnValue = gnutls_record_recv(*connection->tlsSession, &message, sizeof(struct ClientToServerMessage));
if (returnValue == 0 || returnValue == -10) if (returnValue == 0 || returnValue == -10)
{ {
printf("Closing session ID: %u.\n", *connection->tlsSession); printf("Closing session ID: %u.\n", *connection->tlsSession);
@ -180,6 +185,7 @@ int main (int argc, char ** argv)
gnutls_bye(*connection->tlsSession, 2); gnutls_bye(*connection->tlsSession, 2);
shutdown(connection->fileDescriptor, 2); shutdown(connection->fileDescriptor, 2);
close(connection->fileDescriptor); close(connection->fileDescriptor);
deallocatePlayer(&connection->player);
removeConnectionByFileDescriptor(&clientConnections, connection->fileDescriptor); removeConnectionByFileDescriptor(&clientConnections, connection->fileDescriptor);
} }
else if (returnValue == sizeof(struct ClientToServerMessage)) else if (returnValue == sizeof(struct ClientToServerMessage))
@ -188,18 +194,26 @@ int main (int argc, char ** argv)
// Copy the message to the output format: // Copy the message to the output format:
outputMessage.type = LOCAL_CHAT; 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); strncpy(outputMessage.content, message.content, MESSAGE_CONTENT_LENGTH);
// Echo the message into all other clients: (Temporary)
struct ClientConnectionNode * currentClient = clientConnections.head; struct ClientConnectionNode * currentClient = clientConnections.head;
while (currentClient != NULL) while (currentClient != NULL)
{ {
gnutls_record_send(*currentClient->connection->tlsSession, &outputMessage, gnutls_record_send(*currentClient->connection->tlsSession, &outputMessage,
sizeof(struct ServerToClientMessage)); sizeof(struct ServerToClientMessage));
currentClient = currentClient->next; currentClient = currentClient->next;
} }
// printf("%s\n", message.content);
// fflush(stdout);
} }
} }
else else
@ -216,7 +230,7 @@ int main (int argc, char ** argv)
} }
// Wait for all other threads to terminate: // 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 a successful status code to the operating system:
return 0; return 0;

View File

@ -0,0 +1,40 @@
// =========================================
// | SilverMUD Server - player-data.c |
// | Copyright (C) 2023, Barra Ó Catháin |
// | See end of file for copyright notice. |
// =========================================
#include <stdlib.h>
#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 <https://www.gnu.org/licenses/>.

View File

@ -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 <https://www.gnu.org/licenses/>.