diff --git a/SilverMUD.org b/SilverMUD.org index 070bfe8..0c748ff 100644 --- a/SilverMUD.org +++ b/SilverMUD.org @@ -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 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 to improvise that they have at the table, through simple programming and 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, type a forward-slash (/) followed immediately by the command name. The command can be upper or lower-case. -| Command | Arguments | Effect | -|---------+---------------------------------------------------+--------------------------------------------------------------------| -| JOIN | Takes a 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. | -| LOOK | None | Gives you a description of what's around you, and what you can do. | -| STAT | None | Displays your current status and character sheet. | -| 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. | +| Command | Arguments | Effect | +|---------+------------------------------------------+---------------------------------------------------------| +| JOIN | Character Name | Logs you into the server with the given character name. | +| MOVE | Path Name/Path Number | Moves you down the given path. | +| LOOK | None | Describes the current area. | +| STAT | None | Displays your current status and character sheet. | +| SPEC | Core Stat Name | Allows you to apply spec points to a given stat. | +| TRY | Core Stat Name/Skill Name, Object Number | Attempt to use the given stat or skill on the object. | -** Gamemaster's Guide -*** Running the Server: +* Gamemaster's Guide +** Running the Server: -** Developer's Guide -*** Build Prerequisites: +* Developer's Guide +** Build Prerequisites: SilverMUD has the following dependencies: - GnuTLS - 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: diff --git a/src/client/SilverMUDClient.c b/src/client/SilverMUDClient.c index df6ac0a..8f12c42 100644 --- a/src/client/SilverMUDClient.c +++ b/src/client/SilverMUDClient.c @@ -20,7 +20,7 @@ #include "../texteffects.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 { gnutls_session_t tlsSession; @@ -36,17 +36,22 @@ typedef struct sockaddr sockaddr; // A globally available exit boolean: bool shouldExit = false; +// A function for managing the sending thread: 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; // Repeatedly get input from the user, place it in a userMessage, and send it to the server: while (!shouldExit) { // Print the prompt: - wprintw(threadParameters->window, "\n\n\nCOMM-LINK> "); - if (wgetnstr(threadParameters->window, sendBuffer.messageContent, MAX) == ERR) + wprintw(window, "\n\n\nCOMM-LINK> "); + if (wgetnstr(window, sendBuffer.messageContent, MAX) == ERR) { // Quit if there's any funny business with getting input: pthread_exit(NULL); @@ -59,77 +64,104 @@ void * messageSender(void * parameters) } // Send the message to the log if logging is enabled: - if (threadParameters->loggingFlag == true) + if (loggingFlag == true) { - fputs(sendBuffer.messageContent, threadParameters->loggingStream); - fputs("\n", threadParameters->loggingStream); - fflush(threadParameters->loggingStream); + fputs(sendBuffer.messageContent, loggingStream); + fputs("\n", loggingStream); + fflush(loggingStream); } // Send the message off to the server: - messageSend(threadParameters->tlsSession, &sendBuffer); + messageSend(tlsSession, &sendBuffer); } // Rejoin the main thread: pthread_exit(NULL); } +// A function for managing the receiving thread: 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; userMessage receiveBuffer; bool serverMessage = false; - struct threadparameters *threadParameters = parameters; int screenWidth = getmaxx(threadParameters->window); // Repeatedly take messages from the server and print them to the chat log window: while (!shouldExit) { - returnValue = messageReceive(threadParameters->tlsSession, &receiveBuffer); + // Get the next message: + returnValue = messageReceive(tlsSession, &receiveBuffer); + // Check we haven't been disconnected: - if(returnValue == -10 || returnValue == 0) + if (returnValue == -10 || returnValue == 0) { shouldExit = true; } + + // Check if it's a server message: else if (receiveBuffer.senderName[0] == '\0') { - wrapString(receiveBuffer.messageContent, - strlen(receiveBuffer.messageContent) - 1, screenWidth); + // Check if it's a command to disconnect: if (receiveBuffer.messageContent[0] == '\0') { shouldExit = true; 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; } - slowPrintNcurses("\n", threadParameters->characterDelay, threadParameters->window, true); - slowPrintNcurses(receiveBuffer.messageContent, threadParameters->characterDelay, threadParameters->window, false); - slowPrintNcurses("\n", threadParameters->characterDelay, threadParameters->window, true); + + // Print the message: + slowPrintNcurses("\n", characterDelay, window, true); + slowPrintNcurses(receiveBuffer.messageContent, characterDelay, + window, false); + slowPrintNcurses("\n", characterDelay, window, true); } + // It's a user message: else { + // Fit the string to the screen: wrapString(receiveBuffer.messageContent, strlen(receiveBuffer.messageContent) - 1, 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(": ", threadParameters->loggingStream); - fputs(receiveBuffer.messageContent, threadParameters->loggingStream); - fflush(threadParameters->loggingStream); + fputs(receiveBuffer.senderName, loggingStream); + fputs(": ", loggingStream); + fputs(receiveBuffer.messageContent, 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; } - slowPrintNcurses(receiveBuffer.senderName, threadParameters->characterDelay, threadParameters->window, true); - slowPrintNcurses(": ", threadParameters->characterDelay, threadParameters->window, true); - slowPrintNcurses(receiveBuffer.messageContent, threadParameters->characterDelay, threadParameters->window, false); + + // Print the message: + 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); } @@ -156,54 +188,54 @@ int main(int argc, char ** argv) { switch (currentopt) { - case 'i': - { - memcpy(ipAddress, optarg, 32); - break; - } - case 'c': - { - memcpy(chatLogPath, optarg, PATH_MAX + 1); - chatLog = fopen(chatLogPath, "a+"); - if (chatLog == NULL) + case 'i': { - 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': - { - memcpy(gameLogPath, optarg, PATH_MAX + 1); - gameLog = fopen(gameLogPath, "a+"); - if (gameLog == NULL) + case 'g': { - 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); } - 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_addr.s_addr = inet_addr(ipAddress); 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); 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: gnutls_session_t tlsSession = NULL; if (gnutls_init(&tlsSession, GNUTLS_CLIENT) < 0) - { - // Failure Case + { exit(EXIT_FAILURE); } diff --git a/src/playerdata.h b/src/playerdata.h index e1d679f..8d0ae0c 100644 --- a/src/playerdata.h +++ b/src/playerdata.h @@ -9,10 +9,10 @@ #include "linkedlist.h" // Let the compiler know there will be structs defined elsewhere: -typedef struct playerPath playerPath; typedef struct playerArea playerArea; -typedef struct list list; +typedef struct playerPath playerPath; typedef struct listNode listNode; +typedef struct list list; typedef struct statBlock { diff --git a/tests/outputQueue-test.c b/tests/outputQueue-test.c deleted file mode 100644 index a36fd43..0000000 --- a/tests/outputQueue-test.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "../src/inputoutput.h" -#include -#include -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; -}