Cleaned and styled SilverMUDClient.c
- Brought SilverMUDClient.c to a consistent style. - Cleaned and neatened various parts of SilverMUDClient.c. - Minor cleanup of playerdata.h. - Began writing the SilverMUD Style Guide. - Removed outputQueue-test.c, because outputQueue no longer exists.
This commit is contained in:
parent
6a653c75b9
commit
c2c77d6343
|
@ -1,28 +1,65 @@
|
||||||
|
#+LATEX_HEADER: \RequirePackage[left=0.3in,top=0.3in,right=0.3in,bottom=0.3in, a4paper]{geometry}
|
||||||
* SilverMUD: The Hackable Terminal-Top Roleplaying Game.
|
* SilverMUD: The Hackable Terminal-Top Roleplaying Game.
|
||||||
SilverMUD is a tool for creating engaging and communal stories, all over the
|
SilverMUD is a tool for creating engaging and communal stories, all over the
|
||||||
world through the internet. It's designed to give a gamemaster the same power
|
world through the internet. It's designed to give a gamemaster the same power
|
||||||
to improvise that they have at the table, through simple programming and
|
to improvise that they have at the table, through simple programming and
|
||||||
easy-to-understand structures.
|
easy-to-understand structures.
|
||||||
** Player's Guide
|
|
||||||
*** The Basic Commands
|
* Player's Guide
|
||||||
|
** The Basic Commands
|
||||||
SilverMUD is played through a set of very simple commands. To use a command,
|
SilverMUD is played through a set of very simple commands. To use a command,
|
||||||
type a forward-slash (/) followed immediately by the command name. The command
|
type a forward-slash (/) followed immediately by the command name. The command
|
||||||
can be upper or lower-case.
|
can be upper or lower-case.
|
||||||
|
|
||||||
| Command | Arguments | Effect |
|
| Command | Arguments | Effect |
|
||||||
|---------+---------------------------------------------------+--------------------------------------------------------------------|
|
|---------+------------------------------------------+---------------------------------------------------------|
|
||||||
| JOIN | Takes a character name | Logs you into the server with the given character name. |
|
| JOIN | Character Name | Logs you into the server with the given character name. |
|
||||||
| MOVE | Takes a path name or a path number | Moves you down the given path. |
|
| MOVE | Path Name/Path Number | Moves you down the given path. |
|
||||||
| LOOK | None | Gives you a description of what's around you, and what you can do. |
|
| LOOK | None | Describes the current area. |
|
||||||
| STAT | None | Displays your current status and character sheet. |
|
| STAT | None | Displays your current status and character sheet. |
|
||||||
| SPEC | Core stat name | Allows you to apply spec points to a given stat. |
|
| SPEC | Core Stat Name | Allows you to apply spec points to a given stat. |
|
||||||
| TRY | Core stat name or skill name and an object number | Attempt to use the given stat or skill on the object. |
|
| TRY | Core Stat Name/Skill Name, Object Number | Attempt to use the given stat or skill on the object. |
|
||||||
|
|
||||||
** Gamemaster's Guide
|
* Gamemaster's Guide
|
||||||
*** Running the Server:
|
** Running the Server:
|
||||||
|
|
||||||
** Developer's Guide
|
* Developer's Guide
|
||||||
*** Build Prerequisites:
|
** Build Prerequisites:
|
||||||
SilverMUD has the following dependencies:
|
SilverMUD has the following dependencies:
|
||||||
- GnuTLS
|
- GnuTLS
|
||||||
- ncurses
|
- ncurses
|
||||||
|
|
||||||
|
** C Style Guide:
|
||||||
|
These rules attempt to make the program as visually clear as possible, while
|
||||||
|
some rules may be made based on my own personal tastes.
|
||||||
|
|
||||||
|
- () :: These are parentheses.
|
||||||
|
- [] :: These are brackets.
|
||||||
|
- {} :: These are braces.
|
||||||
|
*** Formatting:
|
||||||
|
**** Control Statements:
|
||||||
|
- A space should be between the keyword and the condition. This is to make
|
||||||
|
control statements visually distinct from function calls.
|
||||||
|
|
||||||
|
- Opening braces should be on the line after the control statement, and closing
|
||||||
|
braces on the line after the last statement, on it's own. This is to make the
|
||||||
|
scope of the control statement easily identifiable.
|
||||||
|
|
||||||
|
- else and else if should always be on a new line, not the same line as an if
|
||||||
|
statement's closing brace. This is to more easily distinguish the seperate
|
||||||
|
blocks.
|
||||||
|
|
||||||
|
- Control statements should never omit braces and do single statements. This is
|
||||||
|
mostly personal preference, but I do think it makes things more clear.
|
||||||
|
|
||||||
|
*** Naming:
|
||||||
|
**** Rule 0: NEVER USE i AND j!
|
||||||
|
Never use the variable names i and j. These are easy to confuse, and often make
|
||||||
|
nested loops awful to read. Name these more descriptively.
|
||||||
|
For example:
|
||||||
|
- If you are using a variable to index an array, name the variable index.
|
||||||
|
- If you are indexing multiple arrays, name it "array name + Index".
|
||||||
|
- If you are using it to count something, call it count, or "name of the
|
||||||
|
thing you are counting + count".
|
||||||
|
|
||||||
|
*** Comments:
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "../texteffects.h"
|
#include "../texteffects.h"
|
||||||
#include "../inputoutput.h"
|
#include "../inputoutput.h"
|
||||||
|
|
||||||
// A struct for bundling all needed paramaters for a thread so we can pass them using a void pointer:
|
// A struct for bundling all needed parameters for a thread so we can pass them using a void pointer:
|
||||||
typedef struct threadparameters
|
typedef struct threadparameters
|
||||||
{
|
{
|
||||||
gnutls_session_t tlsSession;
|
gnutls_session_t tlsSession;
|
||||||
|
@ -36,17 +36,22 @@ typedef struct sockaddr sockaddr;
|
||||||
// A globally available exit boolean:
|
// A globally available exit boolean:
|
||||||
bool shouldExit = false;
|
bool shouldExit = false;
|
||||||
|
|
||||||
|
// A function for managing the sending thread:
|
||||||
void * messageSender(void * parameters)
|
void * messageSender(void * parameters)
|
||||||
{
|
{
|
||||||
struct threadparameters *threadParameters = parameters;
|
threadparameters * threadParameters = parameters;
|
||||||
|
gnutls_session_t tlsSession = threadParameters->tlsSession;
|
||||||
|
FILE * loggingStream = threadParameters->loggingStream;
|
||||||
|
bool loggingFlag = threadParameters->loggingFlag;
|
||||||
|
WINDOW * window = threadParameters->window;
|
||||||
userMessage sendBuffer;
|
userMessage sendBuffer;
|
||||||
|
|
||||||
// Repeatedly get input from the user, place it in a userMessage, and send it to the server:
|
// Repeatedly get input from the user, place it in a userMessage, and send it to the server:
|
||||||
while (!shouldExit)
|
while (!shouldExit)
|
||||||
{
|
{
|
||||||
// Print the prompt:
|
// Print the prompt:
|
||||||
wprintw(threadParameters->window, "\n\n\nCOMM-LINK> ");
|
wprintw(window, "\n\n\nCOMM-LINK> ");
|
||||||
if (wgetnstr(threadParameters->window, sendBuffer.messageContent, MAX) == ERR)
|
if (wgetnstr(window, sendBuffer.messageContent, MAX) == ERR)
|
||||||
{
|
{
|
||||||
// Quit if there's any funny business with getting input:
|
// Quit if there's any funny business with getting input:
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
|
@ -59,77 +64,104 @@ void * messageSender(void * parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the message to the log if logging is enabled:
|
// Send the message to the log if logging is enabled:
|
||||||
if (threadParameters->loggingFlag == true)
|
if (loggingFlag == true)
|
||||||
{
|
{
|
||||||
fputs(sendBuffer.messageContent, threadParameters->loggingStream);
|
fputs(sendBuffer.messageContent, loggingStream);
|
||||||
fputs("\n", threadParameters->loggingStream);
|
fputs("\n", loggingStream);
|
||||||
fflush(threadParameters->loggingStream);
|
fflush(loggingStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the message off to the server:
|
// Send the message off to the server:
|
||||||
messageSend(threadParameters->tlsSession, &sendBuffer);
|
messageSend(tlsSession, &sendBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rejoin the main thread:
|
// Rejoin the main thread:
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A function for managing the receiving thread:
|
||||||
void * messageReceiver(void * parameters)
|
void * messageReceiver(void * parameters)
|
||||||
{
|
{
|
||||||
|
threadparameters * threadParameters = parameters;
|
||||||
|
gnutls_session_t tlsSession = threadParameters->tlsSession;
|
||||||
|
FILE * loggingStream = threadParameters->loggingStream;
|
||||||
|
int characterDelay = threadParameters->characterDelay;
|
||||||
|
bool loggingFlag = threadParameters->loggingFlag;
|
||||||
|
WINDOW * window = threadParameters->window;
|
||||||
|
|
||||||
int returnValue = 0;
|
int returnValue = 0;
|
||||||
userMessage receiveBuffer;
|
userMessage receiveBuffer;
|
||||||
bool serverMessage = false;
|
bool serverMessage = false;
|
||||||
struct threadparameters *threadParameters = parameters;
|
|
||||||
int screenWidth = getmaxx(threadParameters->window);
|
int screenWidth = getmaxx(threadParameters->window);
|
||||||
|
|
||||||
// Repeatedly take messages from the server and print them to the chat log window:
|
// Repeatedly take messages from the server and print them to the chat log window:
|
||||||
while (!shouldExit)
|
while (!shouldExit)
|
||||||
{
|
{
|
||||||
returnValue = messageReceive(threadParameters->tlsSession, &receiveBuffer);
|
// Get the next message:
|
||||||
|
returnValue = messageReceive(tlsSession, &receiveBuffer);
|
||||||
|
|
||||||
// Check we haven't been disconnected:
|
// Check we haven't been disconnected:
|
||||||
if(returnValue == -10 || returnValue == 0)
|
if (returnValue == -10 || returnValue == 0)
|
||||||
{
|
{
|
||||||
shouldExit = true;
|
shouldExit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if it's a server message:
|
||||||
else if (receiveBuffer.senderName[0] == '\0')
|
else if (receiveBuffer.senderName[0] == '\0')
|
||||||
{
|
{
|
||||||
wrapString(receiveBuffer.messageContent,
|
// Check if it's a command to disconnect:
|
||||||
strlen(receiveBuffer.messageContent) - 1, screenWidth);
|
|
||||||
if (receiveBuffer.messageContent[0] == '\0')
|
if (receiveBuffer.messageContent[0] == '\0')
|
||||||
{
|
{
|
||||||
shouldExit = true;
|
shouldExit = true;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
if(serverMessage == false)
|
|
||||||
|
// Fit the string to the screen:
|
||||||
|
wrapString(receiveBuffer.messageContent, strlen(receiveBuffer.messageContent) - 1, screenWidth);
|
||||||
|
|
||||||
|
// If it's the first server message in a block, begin a block of server messages:
|
||||||
|
if (serverMessage == false)
|
||||||
{
|
{
|
||||||
slowPrintNcurses("\n --====<>====--", threadParameters->characterDelay, threadParameters->window, true);
|
slowPrintNcurses("\n --====<>====--", characterDelay, window, true);
|
||||||
serverMessage = true;
|
serverMessage = true;
|
||||||
}
|
}
|
||||||
slowPrintNcurses("\n", threadParameters->characterDelay, threadParameters->window, true);
|
|
||||||
slowPrintNcurses(receiveBuffer.messageContent, threadParameters->characterDelay, threadParameters->window, false);
|
// Print the message:
|
||||||
slowPrintNcurses("\n", threadParameters->characterDelay, threadParameters->window, true);
|
slowPrintNcurses("\n", characterDelay, window, true);
|
||||||
|
slowPrintNcurses(receiveBuffer.messageContent, characterDelay,
|
||||||
|
window, false);
|
||||||
|
slowPrintNcurses("\n", characterDelay, window, true);
|
||||||
}
|
}
|
||||||
|
// It's a user message:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Fit the string to the screen:
|
||||||
wrapString(receiveBuffer.messageContent, strlen(receiveBuffer.messageContent) - 1,
|
wrapString(receiveBuffer.messageContent, strlen(receiveBuffer.messageContent) - 1,
|
||||||
screenWidth - strlen(receiveBuffer.senderName) - 2);
|
screenWidth - strlen(receiveBuffer.senderName) - 2);
|
||||||
if (threadParameters->loggingFlag == true)
|
|
||||||
|
// If the user has requested logging, insert the message into the file:
|
||||||
|
if (loggingFlag == true)
|
||||||
{
|
{
|
||||||
fputs(receiveBuffer.senderName, threadParameters->loggingStream);
|
fputs(receiveBuffer.senderName, loggingStream);
|
||||||
fputs(": ", threadParameters->loggingStream);
|
fputs(": ", loggingStream);
|
||||||
fputs(receiveBuffer.messageContent, threadParameters->loggingStream);
|
fputs(receiveBuffer.messageContent, loggingStream);
|
||||||
fflush(threadParameters->loggingStream);
|
fflush(loggingStream);
|
||||||
}
|
}
|
||||||
if(serverMessage == true)
|
|
||||||
|
// If we're in a block of server messages, end it:
|
||||||
|
if (serverMessage == true)
|
||||||
{
|
{
|
||||||
slowPrintNcurses("\n --====<>====-- \n", threadParameters->characterDelay, threadParameters->window, true);
|
slowPrintNcurses("\n --====<>====-- \n", characterDelay, window, true);
|
||||||
serverMessage = false;
|
serverMessage = false;
|
||||||
}
|
}
|
||||||
slowPrintNcurses(receiveBuffer.senderName, threadParameters->characterDelay, threadParameters->window, true);
|
|
||||||
slowPrintNcurses(": ", threadParameters->characterDelay, threadParameters->window, true);
|
// Print the message:
|
||||||
slowPrintNcurses(receiveBuffer.messageContent, threadParameters->characterDelay, threadParameters->window, false);
|
slowPrintNcurses(receiveBuffer.senderName, characterDelay, window, true);
|
||||||
|
slowPrintNcurses(": ", characterDelay, window, true);
|
||||||
|
slowPrintNcurses(receiveBuffer.messageContent, characterDelay, window, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Exit the thread if shouldExit is true:
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,54 +188,54 @@ int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
switch (currentopt)
|
switch (currentopt)
|
||||||
{
|
{
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
|
||||||
memcpy(ipAddress, optarg, 32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c':
|
|
||||||
{
|
|
||||||
memcpy(chatLogPath, optarg, PATH_MAX + 1);
|
|
||||||
chatLog = fopen(chatLogPath, "a+");
|
|
||||||
if (chatLog == NULL)
|
|
||||||
{
|
{
|
||||||
chatLogging = false;
|
memcpy(ipAddress, optarg, 32);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case 'c':
|
||||||
{
|
{
|
||||||
chatLogging = true;
|
memcpy(chatLogPath, optarg, PATH_MAX + 1);
|
||||||
|
chatLog = fopen(chatLogPath, "a+");
|
||||||
|
if (chatLog == NULL)
|
||||||
|
{
|
||||||
|
chatLogging = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chatLogging = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case 'g':
|
||||||
}
|
|
||||||
case 'g':
|
|
||||||
{
|
|
||||||
memcpy(gameLogPath, optarg, PATH_MAX + 1);
|
|
||||||
gameLog = fopen(gameLogPath, "a+");
|
|
||||||
if (gameLog == NULL)
|
|
||||||
{
|
{
|
||||||
gameLogging = false;
|
memcpy(gameLogPath, optarg, PATH_MAX + 1);
|
||||||
|
gameLog = fopen(gameLogPath, "a+");
|
||||||
|
if (gameLog == NULL)
|
||||||
|
{
|
||||||
|
gameLogging = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameLogging = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case 'p':
|
||||||
{
|
{
|
||||||
gameLogging = true;
|
port = atoi(optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd':
|
||||||
|
{
|
||||||
|
characterDelay = atoi(optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '?':
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'p':
|
|
||||||
{
|
|
||||||
port = atoi(optarg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'd':
|
|
||||||
{
|
|
||||||
characterDelay = atoi(optarg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '?':
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,9 +250,8 @@ int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
slowPrint("Socket successfully created.\n", characterDelay);
|
slowPrint("Socket successfully created.\n", characterDelay);
|
||||||
}
|
}
|
||||||
bzero(&serverAddress, sizeof(serverAddress));
|
|
||||||
|
|
||||||
// Set our IP Address and port. Default to localhost for testing:
|
// Set our IP address and port. Default to localhost for testing:
|
||||||
serverAddress.sin_family = AF_INET;
|
serverAddress.sin_family = AF_INET;
|
||||||
serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
|
serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
|
||||||
serverAddress.sin_port = htons(port);
|
serverAddress.sin_port = htons(port);
|
||||||
|
@ -231,17 +262,11 @@ int main(int argc, char ** argv)
|
||||||
slowPrint("Connection with the Silverkin Industries Comm-Link Server Failed:\nPlease contact your service representative.\n", characterDelay);
|
slowPrint("Connection with the Silverkin Industries Comm-Link Server Failed:\nPlease contact your service representative.\n", characterDelay);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
slowPrint("Connected to the Silverkin Industries Comm-Link Server:\nHave a pleasant day.\n", characterDelay);
|
|
||||||
}
|
|
||||||
usleep(100000);
|
|
||||||
|
|
||||||
// Setup a GnuTLS session and initialize it:
|
// Setup a GnuTLS session and initialize it:
|
||||||
gnutls_session_t tlsSession = NULL;
|
gnutls_session_t tlsSession = NULL;
|
||||||
if (gnutls_init(&tlsSession, GNUTLS_CLIENT) < 0)
|
if (gnutls_init(&tlsSession, GNUTLS_CLIENT) < 0)
|
||||||
{
|
{
|
||||||
// Failure Case
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include "linkedlist.h"
|
#include "linkedlist.h"
|
||||||
|
|
||||||
// Let the compiler know there will be structs defined elsewhere:
|
// Let the compiler know there will be structs defined elsewhere:
|
||||||
typedef struct playerPath playerPath;
|
|
||||||
typedef struct playerArea playerArea;
|
typedef struct playerArea playerArea;
|
||||||
typedef struct list list;
|
typedef struct playerPath playerPath;
|
||||||
typedef struct listNode listNode;
|
typedef struct listNode listNode;
|
||||||
|
typedef struct list list;
|
||||||
|
|
||||||
typedef struct statBlock
|
typedef struct statBlock
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
#include "../src/inputoutput.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
userMessage A, B, C;
|
|
||||||
strncpy(A.senderName, "Bob\0", 32 -1);
|
|
||||||
strncpy(A.messageContent, "joins the fray!\0", MAX-1);
|
|
||||||
strncpy(B.senderName, "Alice\0", 32 -1);
|
|
||||||
strncpy(B.messageContent, "challenges the unknown!\0", MAX -1);
|
|
||||||
strncpy(C.senderName, "Tom\0", 32 -1);
|
|
||||||
strncpy(C.messageContent, "Attacks them all!\0", MAX -1);
|
|
||||||
outputMessageQueue * testQueue = createOutputMessageQueue();
|
|
||||||
printf("Queue Created.\n");
|
|
||||||
printf("%d", queueOutputMessage(testQueue, A));
|
|
||||||
printf("Queued A.\n");
|
|
||||||
printf("%d", queueOutputMessage(testQueue, B));
|
|
||||||
printf("Queued B.\n");
|
|
||||||
printf("%d", queueOutputMessage(testQueue, C));
|
|
||||||
printf("Queued C.\n");
|
|
||||||
printf("%s\n", testQueue->front->content->senderName);
|
|
||||||
printf("%s\n", testQueue->front->content->messageContent);
|
|
||||||
printf("%s\n", testQueue->front->next->content->senderName);
|
|
||||||
printf("%s\n", testQueue->front->next->content->messageContent);
|
|
||||||
printf("%s\n", testQueue->front->next->next->content->senderName);
|
|
||||||
printf("%s\n", testQueue->front->next->next->content->messageContent);
|
|
||||||
printf("%s\n", testQueue->front->content->senderName);
|
|
||||||
dequeueOutputMessage(testQueue);
|
|
||||||
printf("%s\n", testQueue->front->content->senderName);
|
|
||||||
dequeueOutputMessage(testQueue);
|
|
||||||
printf("%s\n", testQueue->front->content->senderName);
|
|
||||||
// dequeueOutputMessage(testQueue);
|
|
||||||
// printf("%s\n", testQueue->front->content->senderName);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue