Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bots

Development::Bots Forum for bots.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #15  
Old 02-22-2013, 05:37 PM
zippzipp
Fire Beetle
 
Join Date: Dec 2012
Posts: 14
Default

So it turns out the issue was seeded much deeper than I had realized. While the fixes posted before fixed issues with creating bots with same name, they did not fix the issue of that player with the same name going Linkdead when another user attempted to create a bot with their name.

The problem was rooted in the fact that the function in bot.cpp:

Bot::IsBotNameAvailable is a non-static class function and a Bot object was needed in order to check if the name was valid. Creating that Bot object was crashing people with the same name. What I did was make the IsBotNameAvailable a static class function and pass it the name to check. I then call the function before the new Bot object is created. This fixes the problem of crashing and prevents people from making bots with the same name as PCs.

Code:
// Bot.h
// modify the IsBotNameAvailable function prototype

// REPLACE THIS:
bool IsBotNameAvailable(std::string* errorMessage);
// WITH THIS:
static bool IsBotNameAvailable(char *botName, std::string* errorMessage);
Code:
// Bot.cpp
// modify the IsBotNameAvailable function to work off without a this pointer.

bool Bot::IsBotNameAvailable(char *botName, std::string* errorMessage) {
	bool Result1 = false;
	bool Result2 = false;

	if(botName !="") {
		char* Query = 0;
		char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
		MYSQL_RES* DatasetResult;
		MYSQL_ROW DataRow;

		if(!database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT COUNT(id) FROM vwBotCharacterMobs WHERE name LIKE '%s'", botName), TempErrorMessageBuffer, &DatasetResult)) {
			*errorMessage = std::string(TempErrorMessageBuffer);
		}
		else {
			uint32 ExistingNameCount = 0;

			while(DataRow = mysql_fetch_row(DatasetResult)) {
				ExistingNameCount = atoi(DataRow[0]);
				break;
			}

			if(ExistingNameCount == 0)
				Result1 = true;

			mysql_free_result(DatasetResult);

			if(!database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT COUNT(id) FROM character_ WHERE name LIKE '%s'", botName), TempErrorMessageBuffer, &DatasetResult)) {
				*errorMessage = std::string(TempErrorMessageBuffer);
			} else {
				uint32 ExistingNameCount = 0;

				while(DataRow = mysql_fetch_row(DatasetResult)) {
					ExistingNameCount = atoi(DataRow[0]);
					break;
				}

				if(ExistingNameCount == 0)
					Result2 = true;

				mysql_free_result(DatasetResult);

			}
		}
		safe_delete(Query);
	}

	if(Result1 && Result2)
		return true;
	else
		return false;
}
Modify all references to IsBotNameAvailable to call the static function.

Code:
// bot.cpp
// REPLACE:
NPCType DefaultNPCTypeStruct = CreateDefaultNPCTypeStructForBot(std::string(sep->arg[2]), std::string(), c->GetLevel(), atoi(sep->arg[4]), atoi(sep->arg[3]), gender);
		Bot* NewBot = new Bot(DefaultNPCTypeStruct, c);

// WITH:
if(!IsBotNameAvailable(sep->arg[2],&TempErrorMessage)) {
			c->Message(0, "The name %s is already being used. Please choose a different name.", sep->arg[2]);
			return;
		}

		NPCType DefaultNPCTypeStruct = CreateDefaultNPCTypeStructForBot(std::string(sep->arg[2]), std::string(), c->GetLevel(), atoi(sep->arg[4]), atoi(sep->arg[3]), gender);
		Bot* NewBot = new Bot(DefaultNPCTypeStruct, c);


// REMOVE THIS:
if(!NewBot->IsBotNameAvailable(&TempErrorMessage)) {
			c->Message(0, "The name %s is already being used. Please choose a different name.", NewBot->GetCleanName());
			return;
		}
ALSO update questmgr.cpp for when a bot is created via quest.
Code:
// questmgr.cpp
// REPLACE:
NPCType DefaultNPCTypeStruct = Bot::CreateDefaultNPCTypeStructForBot(name, lastname, level, race, botclass, gender);
		Bot* NewBot = new Bot(DefaultNPCTypeStruct, initiator);

// WITH:
if(Bot::IsBotNameAvailable((char*)name,&TempErrorMessage)) {
			initiator->Message(0, "The name %s is already being used. Please choose a different name.", (char*)name);
			return false;
		}

		NPCType DefaultNPCTypeStruct = Bot::CreateDefaultNPCTypeStructForBot(name, lastname, level, race, botclass, gender);
		Bot* NewBot = new Bot(DefaultNPCTypeStruct, initiator);


// REMOVE THIS:
if(!NewBot->IsBotNameAvailable(&TempErrorMessage)) {
			initiator->Message(0, "The name %s is already being used. Please choose a different name.", NewBot->GetCleanName());
			return false;
		}
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 07:16 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3