Compare commits
3 Commits
3fc75ef30f
...
a1b1b80449
Author | SHA1 | Date |
---|---|---|
Barra Ó Catháin | a1b1b80449 | |
Barra Ó Catháin | 54b613befe | |
Barra Ó Catháin | 5a53e9f197 |
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#+TITLE: SilverMUD: Gamemaster's Guidebook
|
||||||
|
#+SUBTITLE: SilverMUD First Edition
|
||||||
|
#+AUTHOR: Barra Ó Catháin
|
||||||
|
|
||||||
|
* How To Run SilverMUD, The Software:
|
||||||
|
|
||||||
|
* How To Run SilverMUD, The Game:
|
||||||
|
|
||||||
|
* Creating Content:
|
|
@ -0,0 +1,15 @@
|
||||||
|
#+TITLE: SilverMUD: Player's Guidebook
|
||||||
|
#+SUBTITLE: SilverMUD First Edition
|
||||||
|
#+AUTHOR: Barra Ó Catháin
|
||||||
|
|
||||||
|
* Getting Started:
|
||||||
|
|
||||||
|
* Basic Commands:
|
||||||
|
|
||||||
|
* Interacting With The World:
|
||||||
|
|
||||||
|
* The Character System:
|
||||||
|
|
||||||
|
* The Combat System:
|
||||||
|
|
||||||
|
* Commands In Depth:
|
|
@ -0,0 +1,10 @@
|
||||||
|
#+TITLE: SilverMUD: Programmer's Guidebook
|
||||||
|
#+SUBTITLE: SilverMUD First Edition
|
||||||
|
#+AUTHOR: Barra Ó Catháin
|
||||||
|
|
||||||
|
* The Scheme Programming Language:
|
||||||
|
|
||||||
|
* The Basic Concepts Of SilverMUD Programming:
|
||||||
|
|
||||||
|
* Concepts In Detail:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ SilverMUD, as a scratchpad for decisions before implementation.
|
||||||
| 3 | Local Chat Message |
|
| 3 | Local Chat Message |
|
||||||
| 4 | Player Chat Message |
|
| 4 | Player Chat Message |
|
||||||
| 5 | Party Chat Message |
|
| 5 | Party Chat Message |
|
||||||
|
| 6 | Player Emote Message |
|
||||||
|-------+------------------------|
|
|-------+------------------------|
|
||||||
|
|
||||||
Further values remain open for possible additional message types.
|
Further values remain open for possible additional message types.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "connections.h"
|
#include "connections.h"
|
||||||
|
|
||||||
struct ClientConnectionNode * findMiddle(struct ClientConnectionNode * start, struct ClientConnectionNode * end)
|
static struct ClientConnectionNode * findMiddle(struct ClientConnectionNode * start, struct ClientConnectionNode * end)
|
||||||
{
|
{
|
||||||
while (start != end)
|
while (start != end)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
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
|
||||||
// ===================================================
|
// ===================================================
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -101,6 +102,9 @@ int main (int argc, char ** argv)
|
||||||
// Create a client connection list to allow us to associate TLS sessions and sockets and players:
|
// Create a client connection list to allow us to associate TLS sessions and sockets and players:
|
||||||
struct ClientConnectionList clientConnections;
|
struct ClientConnectionList clientConnections;
|
||||||
|
|
||||||
|
// Create some structures needed to store global state:
|
||||||
|
struct PlayerList * globalPlayerList = createPlayerList();
|
||||||
|
|
||||||
// Start a REPL thread:
|
// Start a REPL thread:
|
||||||
//pthread_t schemeREPLThread;
|
//pthread_t schemeREPLThread;
|
||||||
//pthread_create(&schemeREPLThread, NULL, schemeREPLHandler, NULL);
|
//pthread_create(&schemeREPLThread, NULL, schemeREPLHandler, NULL);
|
||||||
|
@ -141,7 +145,6 @@ int main (int argc, char ** argv)
|
||||||
handshakeReturnValue = gnutls_handshake(*tlsSession);
|
handshakeReturnValue = gnutls_handshake(*tlsSession);
|
||||||
} while (handshakeReturnValue < 0 && gnutls_error_is_fatal(handshakeReturnValue) == 0);
|
} while (handshakeReturnValue < 0 && gnutls_error_is_fatal(handshakeReturnValue) == 0);
|
||||||
|
|
||||||
|
|
||||||
// If the handshake was unsuccessful, close the connection:
|
// If the handshake was unsuccessful, close the connection:
|
||||||
if (handshakeReturnValue < 0)
|
if (handshakeReturnValue < 0)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +162,11 @@ 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", globalPlayerList->count + 1);
|
||||||
|
addToPlayerList(newConnection->player, globalPlayerList);
|
||||||
|
|
||||||
|
|
||||||
// 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,16 +178,18 @@ 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)
|
||||||
{
|
{
|
||||||
|
// Read the data from the TLS session:
|
||||||
struct ClientToServerMessage message;
|
struct ClientToServerMessage message;
|
||||||
int returnValue = gnutls_record_recv(*connection->tlsSession, &message, sizeof(struct ClientToServerMessage));
|
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);
|
|
||||||
epoll_ctl(connectedClients, EPOLL_CTL_DEL, connection->fileDescriptor, &watchedEvents);
|
epoll_ctl(connectedClients, EPOLL_CTL_DEL, connection->fileDescriptor, &watchedEvents);
|
||||||
gnutls_bye(*connection->tlsSession, 2);
|
|
||||||
shutdown(connection->fileDescriptor, 2);
|
shutdown(connection->fileDescriptor, 2);
|
||||||
close(connection->fileDescriptor);
|
|
||||||
removeConnectionByFileDescriptor(&clientConnections, connection->fileDescriptor);
|
removeConnectionByFileDescriptor(&clientConnections, connection->fileDescriptor);
|
||||||
|
close(connection->fileDescriptor);
|
||||||
|
//deallocatePlayer(&connection->player);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (returnValue == sizeof(struct ClientToServerMessage))
|
else if (returnValue == sizeof(struct ClientToServerMessage))
|
||||||
{
|
{
|
||||||
|
@ -188,9 +197,19 @@ 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;
|
||||||
|
|
||||||
|
if (connection->player != NULL)
|
||||||
|
{
|
||||||
|
strncpy(outputMessage.name, connection->player->name, 64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sprintf(outputMessage.name, "UNNAMED");
|
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)
|
||||||
{
|
{
|
||||||
|
@ -198,8 +217,6 @@ int main (int argc, char ** argv)
|
||||||
sizeof(struct ServerToClientMessage));
|
sizeof(struct ServerToClientMessage));
|
||||||
currentClient = currentClient->next;
|
currentClient = currentClient->next;
|
||||||
}
|
}
|
||||||
// printf("%s\n", message.content);
|
|
||||||
// fflush(stdout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -218,6 +235,9 @@ 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);
|
||||||
|
|
||||||
|
// Deallocate the global state structures:
|
||||||
|
deallocatePlayerList(&globalPlayerList);
|
||||||
|
|
||||||
// Return a successful status code to the operating system:
|
// Return a successful status code to the operating system:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
// =========================================
|
||||||
|
// | SilverMUD Server - player-data.c |
|
||||||
|
// | Copyright (C) 2023, Barra Ó Catháin |
|
||||||
|
// | See end of file for copyright notice. |
|
||||||
|
// =========================================
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "player-data.h"
|
||||||
|
|
||||||
|
// Internal Functions:
|
||||||
|
// ===================
|
||||||
|
static struct PlayerListNode * findMiddle(struct PlayerListNode * start, struct PlayerListNode * end)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
{
|
||||||
|
start = start->next;
|
||||||
|
if(start == end)
|
||||||
|
{
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
end = end->previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PlayerList * createPlayerList()
|
||||||
|
{
|
||||||
|
struct PlayerList * newPlayerList = calloc(1, sizeof(struct PlayerList));
|
||||||
|
newPlayerList->count = 0;
|
||||||
|
newPlayerList->head = NULL;
|
||||||
|
newPlayerList->tail = NULL;
|
||||||
|
|
||||||
|
return newPlayerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocatePlayerList(struct PlayerList ** playerList)
|
||||||
|
{
|
||||||
|
struct PlayerListNode * node = (*playerList)->head, * nextNode;
|
||||||
|
|
||||||
|
// Deallocate all nodes in the list:
|
||||||
|
while (node != NULL)
|
||||||
|
{
|
||||||
|
nextNode = node->next;
|
||||||
|
free(node);
|
||||||
|
node = nextNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deallocate the list itself:
|
||||||
|
free(*playerList);
|
||||||
|
|
||||||
|
// Set the pointer to null:
|
||||||
|
playerList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addToPlayerList(struct Player * player, struct PlayerList * playerList)
|
||||||
|
{
|
||||||
|
// Check that the player isn't already in the list:
|
||||||
|
if (isInPlayerList(player, playerList))
|
||||||
|
{
|
||||||
|
return playerList->count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a node to add to the list:
|
||||||
|
struct PlayerListNode * newNode = calloc(1, sizeof(struct PlayerListNode));
|
||||||
|
newNode->player = player;
|
||||||
|
newNode->next = NULL;
|
||||||
|
newNode->previous = NULL;
|
||||||
|
|
||||||
|
// Find the position that the new node is to go into:
|
||||||
|
|
||||||
|
// If the list is empty:
|
||||||
|
if (playerList->count == 0)
|
||||||
|
{
|
||||||
|
playerList->head = newNode;
|
||||||
|
playerList->tail = newNode;
|
||||||
|
playerList->count = 1;
|
||||||
|
return playerList->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PlayerListNode * currentNode = playerList->head;
|
||||||
|
while (strncmp(player->name, currentNode->player->name, 64) < 0)
|
||||||
|
{
|
||||||
|
// If we reach the end of the list:
|
||||||
|
if (currentNode->next == NULL)
|
||||||
|
{
|
||||||
|
currentNode->next = newNode;
|
||||||
|
newNode->previous = currentNode;
|
||||||
|
playerList->tail = newNode;
|
||||||
|
playerList->count++;
|
||||||
|
|
||||||
|
return playerList->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the appropriate pointers in the new node:
|
||||||
|
newNode->previous = currentNode->previous;
|
||||||
|
currentNode->previous = newNode;
|
||||||
|
newNode->next = currentNode;
|
||||||
|
|
||||||
|
// Set the proper pointers if we're at the ends of the list:
|
||||||
|
if (newNode->previous == NULL)
|
||||||
|
{
|
||||||
|
playerList->head = newNode;
|
||||||
|
}
|
||||||
|
if (newNode->next == NULL)
|
||||||
|
{
|
||||||
|
playerList->tail = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerList->count++;
|
||||||
|
|
||||||
|
return playerList->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the Player with the given name from a PlayerList, or NULL otherwise:
|
||||||
|
struct Player * getFromPlayerList(char * playerName, struct PlayerList * playerList)
|
||||||
|
{
|
||||||
|
struct PlayerListNode * start = playerList->head, * end = playerList->tail, * middle = findMiddle(start, end);
|
||||||
|
int returnValue = 0;
|
||||||
|
|
||||||
|
while (start != end)
|
||||||
|
{
|
||||||
|
returnValue = strncmp(middle->player->name, playerName, 64);
|
||||||
|
|
||||||
|
if (returnValue < 0)
|
||||||
|
{
|
||||||
|
start = middle->next;
|
||||||
|
middle = findMiddle(start, end);
|
||||||
|
}
|
||||||
|
else if (returnValue > 0)
|
||||||
|
{
|
||||||
|
end = middle->next;
|
||||||
|
middle = findMiddle(start, end);
|
||||||
|
}
|
||||||
|
else if (returnValue == 0)
|
||||||
|
{
|
||||||
|
return middle->player;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strncmp(start->player->name, playerName, 64) == 0)
|
||||||
|
{
|
||||||
|
return start->player;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the given Player is in the given PlayerList:
|
||||||
|
bool isInPlayerList(struct Player * player, struct PlayerList * playerList)
|
||||||
|
{
|
||||||
|
struct PlayerListNode * currentNode = playerList->head;
|
||||||
|
while (currentNode != NULL)
|
||||||
|
{
|
||||||
|
if (currentNode->player == player)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
currentNode = currentNode->next;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
// | 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/>.
|
|
@ -0,0 +1,79 @@
|
||||||
|
// =========================================
|
||||||
|
// | 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 <stdbool.h>
|
||||||
|
#include "connections.h"
|
||||||
|
|
||||||
|
// =================================================================
|
||||||
|
// Players - A structure for representing a single player character:
|
||||||
|
// =================================================================
|
||||||
|
struct Player
|
||||||
|
{
|
||||||
|
struct ClientConnection * connection;
|
||||||
|
char name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions:
|
||||||
|
// ==========
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// ========================================================================================
|
||||||
|
// Player Lists - A structure for managing a collection of players in a doubly linked list:
|
||||||
|
// ========================================================================================
|
||||||
|
struct PlayerListNode
|
||||||
|
{
|
||||||
|
struct Player * player;
|
||||||
|
struct PlayerListNode * next, * previous;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerList
|
||||||
|
{
|
||||||
|
size_t count;
|
||||||
|
struct PlayerListNode * head, * tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions:
|
||||||
|
// ==========
|
||||||
|
|
||||||
|
struct PlayerList * createPlayerList();
|
||||||
|
void deallocatePlayerList(struct PlayerList ** playerList);
|
||||||
|
|
||||||
|
// Adds a Player into a PlayerList, in a sorted position by character name.
|
||||||
|
// Returns the count of players in the list:
|
||||||
|
int addToPlayerList(struct Player * player, struct PlayerList * playerList);
|
||||||
|
|
||||||
|
// Remove a Player from a PlayerList. Returns the count of players in the list:
|
||||||
|
int removeFromPlayerList(struct Player * player, struct PlayerList * playerList);
|
||||||
|
|
||||||
|
// Returns the Player with the given name from a PlayerList, or NULL otherwise:
|
||||||
|
struct Player * getFromPlayerList(char * playerName, struct PlayerList * playerList);
|
||||||
|
|
||||||
|
// Returns true if the given Player is in the given PlayerList:
|
||||||
|
bool isInPlayerList(struct Player * player, struct PlayerList * playerList);
|
||||||
|
|
||||||
|
#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/>.
|
|
@ -5,23 +5,7 @@
|
||||||
// ===========================================
|
// ===========================================
|
||||||
#include <libguile.h>
|
#include <libguile.h>
|
||||||
|
|
||||||
#include "scheme-integration.h"
|
SCM scheme_get_player_by_name(SCM name);
|
||||||
|
|
||||||
// The function ran by the Scheme thread which runs a text-based REPL:
|
|
||||||
void * schemeREPLHandler (void * threadParameters)
|
|
||||||
{
|
|
||||||
// Initialize Scheme:
|
|
||||||
scm_init_guile();
|
|
||||||
|
|
||||||
// Enable Readline support:
|
|
||||||
scm_c_eval_string("(begin (use-modules (ice-9 readline)) (activate-readline))");
|
|
||||||
|
|
||||||
// Start a Scheme REPL:
|
|
||||||
scm_shell(0, NULL);
|
|
||||||
|
|
||||||
// Return NULL to the calling thread:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================================
|
// ==========================================================
|
||||||
// | End of scheme-integration.c, copyright notice follows. |
|
// | End of scheme-integration.c, copyright notice follows. |
|
||||||
|
|
|
@ -6,13 +6,7 @@
|
||||||
#ifndef SCHEME_INTEGRATION_H
|
#ifndef SCHEME_INTEGRATION_H
|
||||||
#define SCHEME_INTEGRATION_H
|
#define SCHEME_INTEGRATION_H
|
||||||
|
|
||||||
struct SchemeThreadArguments
|
SCM scheme_get_player_by_name(SCM name);
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// The function ran by the Scheme thread which initializes the REPL:
|
|
||||||
void * schemeREPLHandler (void * threadParameters);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// ==========================================================
|
// ==========================================================
|
||||||
|
|
Loading…
Reference in New Issue