Updated the evaluateNextCommand to use a hash instead of strncmp

- Added hashCommand.
- Refactored evaluateNextCommand to use hashCommand to jump to the correct functionality with a switch.
This commit is contained in:
Barry Kane 2023-02-19 00:32:03 +00:00
parent e6a13ed2ac
commit afedf15c63
2 changed files with 406 additions and 358 deletions

View File

@ -158,64 +158,12 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
{ {
return -1; return -1;
} }
// Try command: Attempt to use a stat or skill on an object:
if (strncmp(currentCommand->command, "try", 3) == 0) // Hash the command and execute the relevant functionality:
switch (hashCommand(currentCommand->command, strlen(currentCommand->command)))
{ {
userMessage * tryMessage = malloc(sizeof(userMessage));
tryMessage->senderName[0] = '\0';
// Temporary message until we can implement objects, events, and challenges.
strcpy(tryMessage->messageContent, "The try command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * tryOutputMessage = createTargetedOutputMessage(tryMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, tryOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(tryMessage);
}
// Exit command: Sends an "empty" exit message to disconnect a client:
if (strncmp(currentCommand->command, "exit", 4) == 0)
{
// Allocate a userMessage containing null characters as the first char in both fields:
userMessage * exitMessage = malloc(sizeof(userMessage));
exitMessage->senderName[0] = '\0';
exitMessage->messageContent[0] = '\0';
// Allocate an outputMessage for the queue:
outputMessage * exitOutputMessage = createTargetedOutputMessage(exitMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, exitOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage
free(exitMessage);
}
// Move command: Moves the caller to a different area given a path name or number:
if (strncmp(currentCommand->command, "move", 4) == 0)
{
char requestedPath[32];
if (strlen(currentCommand->arguments) > 0 && currentCommand->caller->currentArea != getFromList(parameters->areaList, 0)->area)
{
memcpy(requestedPath, currentCommand->arguments, 32);
userNameSanatize(requestedPath, 32);
requestedPath[31] = '\0';
if (movePlayerToArea(currentCommand->caller, requestedPath) == 0)
{
// Call the look command after moving. It's fine to unlock, because the loop won't
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
}
}
}
// Look command: Returns the description of the current area and paths: // Look command: Returns the description of the current area and paths:
if (strncmp(currentCommand->command, "look", 4) == 0) case 5626697:
{ {
char formattedString[64]; char formattedString[64];
userMessage * lookMessage = calloc(1, sizeof(userMessage)); userMessage * lookMessage = calloc(1, sizeof(userMessage));
@ -263,57 +211,12 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE); pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE);
} }
free(lookMessage); free(lookMessage);
}
// Join command: Allows the player to join the game given a name:
// TODO: Implement login/character creation. Will be a while:
if (strncmp(currentCommand->command, "join", 4) == 0)
{
if (currentCommand->caller->currentArea == getFromList(parameters->areaList, 0)->area)
{
bool validName = true;
for(int index = 0; index < *parameters->playerCount; index++)
{
if (currentCommand->arguments[0] == '\0')
{
validName = false;
}
if (strncmp(currentCommand->arguments, parameters->connectedPlayers[index].playerName, 16) == 0)
{
validName = false;
}
}
if (validName)
{
strncpy(currentCommand->caller->playerName, currentCommand->arguments, 16);
currentCommand->caller->currentArea = getFromList(parameters->areaList, 1)->area;
// Call the look command after joining. It's fine to unlock, because the loop won't
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
}
}
}
// Talk command: Allows the player to begin a chat session with another player:
if (strncmp(currentCommand->command, "talk", 4) == 0)
{
userMessage * talkMessage = malloc(sizeof(userMessage));
talkMessage->senderName[0] = '\0';
// Temporary message until we can implement objects, events, and challenges. break;
strcpy(talkMessage->messageContent, "The talk command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * talkOutputMessage = createTargetedOutputMessage(talkMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, talkOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(talkMessage);
} }
// Stat command: Displays the current character's sheet. // Stat command: Displays the current character's sheet.
if (strncmp(currentCommand->command, "stat", 4) == 0) case 5987604:
{ {
char * formattedString = calloc(121, sizeof(char)); char * formattedString = calloc(121, sizeof(char));
userMessage * statMessage = calloc(1, sizeof(userMessage)); userMessage * statMessage = calloc(1, sizeof(userMessage));
@ -394,10 +297,12 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
} }
free(statMessage); free(statMessage);
free(formattedString); free(formattedString);
break;
} }
// Spec command: Assign spec points to stats: // Spec command: Assign spec points to stats:
if (strncmp(currentCommand->command, "spec", 4) == 0) case 5982259:
{ {
userMessage * specMessage = calloc(1, sizeof(userMessage)); userMessage * specMessage = calloc(1, sizeof(userMessage));
specMessage->senderName[0] = '\0'; specMessage->senderName[0] = '\0';
@ -477,8 +382,56 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
// Free the finished message: // Free the finished message:
free(specMessage); free(specMessage);
free(formattedString); free(formattedString);
break;
} }
if (strncmp(currentCommand->command, "skill", 5) == 0)
// Try command: Attempt to use a stat or skill on an object:
case 163143:
{
// Allocate the userMessage to send:
userMessage * tryMessage = malloc(sizeof(userMessage));
tryMessage->senderName[0] = '\0';
// Temporary message until we can implement objects, events, and challenges.
strcpy(tryMessage->messageContent, "The try command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * tryOutputMessage = createTargetedOutputMessage(tryMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, tryOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(tryMessage);
break;
}
// Move command: Moves the caller to a different area given a path name or number:
case 5677603:
{
char requestedPath[32];
if (strlen(currentCommand->arguments) > 0 && currentCommand->caller->currentArea != getFromList(parameters->areaList, 0)->area)
{
memcpy(requestedPath, currentCommand->arguments, 32);
userNameSanatize(requestedPath, 32);
requestedPath[31] = '\0';
if (movePlayerToArea(currentCommand->caller, requestedPath) == 0)
{
// Call the look command after moving. It's fine to unlock, because the loop won't
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
}
}
break;
}
// Skill command: Allows you to put skill points into skills:
case 221096235:
{ {
userMessage * skillMessage = calloc(1, sizeof(userMessage)); userMessage * skillMessage = calloc(1, sizeof(userMessage));
skillMessage->senderName[0] = '\0'; skillMessage->senderName[0] = '\0';
@ -515,8 +468,11 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
pushQueue(parameters->outputQueue, skillOutputMessage, OUTPUT_MESSAGE); pushQueue(parameters->outputQueue, skillOutputMessage, OUTPUT_MESSAGE);
free(skillMessage); free(skillMessage);
break;
} }
if (strncmp(currentCommand->command, "listskills", 10) == 0)
// Listskills commands: List all available skills on the server:
case 2395990522:
{ {
userMessage * listMessage = calloc(1, sizeof(userMessage)); userMessage * listMessage = calloc(1, sizeof(userMessage));
char * formattedString = calloc(121, sizeof(char)); char * formattedString = calloc(121, sizeof(char));
@ -561,7 +517,83 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
pushQueue(parameters->outputQueue, listOutputMessage, OUTPUT_MESSAGE); pushQueue(parameters->outputQueue, listOutputMessage, OUTPUT_MESSAGE);
free(listMessage); free(listMessage);
free(formattedString); free(formattedString);
break;
} }
// Talk command: Allows the player to begin a chat session with another player:
case 601264:
{
userMessage * talkMessage = malloc(sizeof(userMessage));
talkMessage->senderName[0] = '\0';
// Temporary message until we can implement objects, events, and challenges.
strcpy(talkMessage->messageContent, "The talk command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * talkOutputMessage = createTargetedOutputMessage(talkMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, talkOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(talkMessage);
break;
}
// Exit command: Sends an "empty" exit message to disconnect a client:
case 5284234:
{
// Allocate a userMessage containing null characters as the first char in both fields:
userMessage * exitMessage = malloc(sizeof(userMessage));
exitMessage->senderName[0] = '\0';
exitMessage->messageContent[0] = '\0';
// Allocate an outputMessage for the queue:
outputMessage * exitOutputMessage = createTargetedOutputMessage(exitMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, exitOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage
free(exitMessage);
break;
}
// Join command: Allows the player to join the game given a name:
// TODO: Implement login/character creation. Will be a while:
case 5525172:
{
if (currentCommand->caller->currentArea == getFromList(parameters->areaList, 0)->area)
{
bool validName = true;
for(int index = 0; index < *parameters->playerCount; index++)
{
if (currentCommand->arguments[0] == '\0')
{
validName = false;
}
if (strncmp(currentCommand->arguments, parameters->connectedPlayers[index].playerName, 16) == 0)
{
validName = false;
}
}
if (validName)
{
strncpy(currentCommand->caller->playerName, currentCommand->arguments, 16);
currentCommand->caller->currentArea = getFromList(parameters->areaList, 1)->area;
// Call the look command after joining. It's fine to unlock, because the loop won't
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
}
}
break;
}
}
// Remove the current command and unlock the queue: // Remove the current command and unlock the queue:
currentCommand = NULL; currentCommand = NULL;
queue->lock = false; queue->lock = false;
@ -736,10 +768,23 @@ int movePlayerToArea(playerInfo * player, char * requestedPath)
if (strncmp(getFromList(player->currentArea->pathList, index)->path->pathName, if (strncmp(getFromList(player->currentArea->pathList, index)->path->pathName,
requestedPath, 32) == 0) requestedPath, 32) == 0)
{ {
printf("%s: %s\n", player->playerName, getFromList(player->currentArea->pathList, index)->path->pathName);
player->currentArea = getFromList(player->currentArea->pathList, index)->path->areaToJoin; player->currentArea = getFromList(player->currentArea->pathList, index)->path->areaToJoin;
return 0; return 0;
} }
} }
return 1; return 1;
} }
// A hash function for distinguishing commands for the game logic handler:
unsigned int hashCommand(char * command, unsigned int commandLength)
{
unsigned int hash = 0;
char * currentCharacter = command;
for (unsigned int index = 0; index < commandLength && *currentCharacter != '\0'; currentCharacter++)
{
hash = 37 * hash + *currentCharacter;
}
return hash;
}

View File

@ -55,6 +55,9 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue);
void queueCommand(queue * queue, char * command, char * arguments, int commandLength, int argumentsLength, void queueCommand(queue * queue, char * command, char * arguments, int commandLength, int argumentsLength,
playerInfo * callingPlayer); playerInfo * callingPlayer);
// A hash function for distinguishing commands for the game logic handler:
unsigned int hashCommand(char * command, unsigned int commandLength);
// ============================ // ============================
// -=[ Gameplay Primitives ]=-: // -=[ Gameplay Primitives ]=-:
// ============================ // ============================