Thread: Zone instancing
View Single Post
  #16  
Old 09-26-2008, 07:44 PM
Rocker8956
Hill Giant
 
Join Date: Sep 2007
Posts: 117
Default

Thanks AndMetal, I honestly didn’t know which method was preferred. Sorry, I don’t have the energy at the moment to switch the int and int32s around. Though I did learn something and now know in the future.

Here is a diff of all the required code. Hopefully I got it all.
With this the only required manual database entry is setting the zone insttype to 1.

Required SQL
Code:
ALTER TABLE `zone` ADD column `insttype` tinyint (1) zerofill unsigned NOT NULL default '0';
ALTER TABLE character_ ADD column `instZflagNum` int(10) unsigned NOT NULL default '0';
ALTER TABLE character_ ADD column `instZOrgID` int(11) NOT NULL default '0';
INSERT INTO variables VALUES ('curInstFlagNum', 2000, 'Determines what instance flag will be handed out next', '2008-09-05 04:46:47');
INSERT INTO variables VALUES ('dfltInstZflag',1000, 'Used to determine if a zone is instanced, must be 1000 or greater', '2008-09-05 04:46:47');
World\Zoneserver.cpp
Line 498 insert
Code:
ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);
Line 508-509 insert
Code:
int server_id;
ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);
if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id)))
World\Zoneserver.cpp
Line 533 insert
Code:
zlog(WORLD__ZONE,"Processing ZTZ for ingress to zone for client %s\n", ztz->name);
ztz->current_zone_id = database.GetInstZoneID(ztz->current_zone_id, ztz->name); //Rocker8956 possible fix for wrong zone shutdown
ZoneServer *egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id);

World\Client.cpp
Line 644 insert
Code:
zoneID = database.GetInstZoneID(zoneID, GetCharName());
Zone\zoning.cpp
Line 122
Code:
//Checks if the zone can be instanced, character has a instance flag, and 
//that the character is not zoning into an instance that is already loaded
if(database.GetInstType(target_zone_id) == 1){
	int32 characterID = database.GetCharacterID(zc->char_name);
	int32 instFlagNum = database.GetCharInstFlagNum(characterID);
	if(instFlagNum >= database.GetDfltInstZFlag())
	{
			int32 charInstZOrgID = database.GetCharInstZOrgID(characterID);
			// If instance flag matches then...
			if(charInstZOrgID == target_zone_id)
			{
				//If instance zone is not in database then it is copied to database
				if(!database.InstZoneLoaded(instFlagNum)) {
					database.LoadInstZone(target_zone_id, instFlagNum);
				}
				target_zone_id = instFlagNum;
			}
	}
}
Common\database.h
Line 201 insert
Code:
	int32	GetCharInstFlagNum(int32 charID);
	int32	GetCharInstZOrgID(int32 charID);
	int32   GetInstZoneID(int32 zoneID, const char* charName);
	void	DeleteInstZone(int32 instZoneID);
	int32   GetDfltInstZFlag();
	void	setCharInstFlag(int charID, int  orgZoneID, int instFlag);
	void	setGroupInstFlagNum(int charID, int orgZoneID, int instFlag);
	void	setRaidInstFlagNum(int charID, int orgZoneID, int instFlag);
	void	incrCurInstFlagNum(int instFlag);
	int		getCurInstFlagNum();
Common\database.cpp Replace Database::GetZoneName
Around Line 1173
Code:
const char* Database::GetZoneName(int32 zoneID, bool ErrorUnknown) {
	if (zonename_array == 0) {
		if (ErrorUnknown)
			return "UNKNOWN";
		else
			return 0;
	}
	if (zoneID > GetDfltInstZFlag())
	{
		char errbuf[MYSQL_ERRMSG_SIZE];
		char *query = 0;
		MYSQL_RES *result;
		MYSQL_ROW row;
		if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZOrgID FROM character_ WHERE instZflagNum=%i", zoneID), errbuf, &result)) {
			safe_delete_array(query);
			if (mysql_num_rows(result) > 0) {
				row = mysql_fetch_row(result);
				int8 tmp = atoi(row[0]);
				mysql_free_result(result);
				return zonename_array[tmp];
			}
			mysql_free_result(result);
		}
		else 
		{
			cerr << "Error in instZOrgID query in database.cpp GetZoneName'" << query << "' " << errbuf << endl;
			safe_delete_array(query);
		}
	}
	else if (zoneID <= max_zonename) {
  		if (zonename_array[zoneID])
  			return zonename_array[zoneID];
  		else {
  			if (ErrorUnknown)
  				return "UNKNOWN";
  			else
  				return 0;
  		}
  	}
	else {
		if (ErrorUnknown)
			return "UNKNOWN";
		else
			return 0;
	}
}
End of Common\database.cpp insert
Code:
int32 Database::GetDfltInstZFlag(){
char errbuf[MYSQL_ERRMSG_SIZE];
   	 char *query = 0;
   	 MYSQL_RES *result;
   	 MYSQL_ROW row;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'dfltInstZflag'"), errbuf, &result))
	{
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1) {
			row = mysql_fetch_row(result);
			int32 tmp = atoi(row[0]);
			mysql_free_result(result);
			return tmp;
		}
		mysql_free_result(result);
	}

	else {
		cerr << "Error in GetDfltInstZFlag query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
	return 0;
}
int32 Database::GetCharInstFlagNum(int32 charID){
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZflagNum FROM character_ WHERE id=%i", charID), errbuf, &result))
	{
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1) {
			row = mysql_fetch_row(result);
			int tmp = atoi(row[0]);
			mysql_free_result(result);
			return tmp;
		}
		mysql_free_result(result);
	}
	else {
		cerr << "Error in GetCharInstFlag Numquery '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
	return 0;
}

int32 Database::GetCharInstZOrgID(int32 charID){
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZOrgID FROM character_ WHERE id=%i", charID), errbuf, &result))
	{
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1) {
			row = mysql_fetch_row(result);
			int32 tmp = atoi(row[0]);
			mysql_free_result(result);
			return tmp;

		}
		mysql_free_result(result);
	}
	else {
		cerr << "Error in GetInstType query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
	return 0;
}
int32 Database::GetInstZoneID(int32 zoneID, const char* charName) {
	if (zoneID == 0)
		return 0;
	int32 charID = GetCharacterID(charName);
	if (zoneID == GetCharInstZOrgID(charID))
	{
		zoneID = GetCharInstFlagNum(charID);
		return zoneID;
	}
	else
		return (zoneID);
}

void Database::DeleteInstZone(int32 instZoneID)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
	if (RunQuery(query, MakeAnyLenString(&query, "DELETE FROM zone WHERE zoneidnumber=%i", instZoneID), errbuf, &result))
	{
		safe_delete_array(query);
		mysql_free_result(result);
	}
	else {
		cerr << "Error in DeleteInstZone query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
}
//Rocker8956
void Database::setGroupInstFlagNum(int charID, int orgZoneID, int instFlag)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	int groupid = 0;
	
	// Find out what group the character is in
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT groupid from group_id where charid=%i", charID), errbuf, &result)) 
	{
		if (mysql_num_rows(result) == 1)
		{
			row = mysql_fetch_row(result);
			groupid=atoi(row[0]);
			mysql_free_result(result);
			safe_delete_array(query);
			// Select the character IDs of the characters in the group
			if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid FROM group_id WHERE groupid=%i", groupid), errbuf, &result))
			{
				while((row = mysql_fetch_row(result))) 
				{
					charID = atoi(row[0]);
					setCharInstFlag(charID, orgZoneID, instFlag);
					Sleep(0);
				}
				safe_delete_array(query);
				mysql_free_result(result);
			}
		}
		else
		{
			printf("Unable to get group id, char not found!\n");
			mysql_free_result(result);
			safe_delete_array(query);
		}
	}
	else
	{
		printf("Unable to get group id: %s\n",errbuf);
		mysql_free_result(result);
		safe_delete_array(query);
	}

}

void Database::setRaidInstFlagNum(int charID, int orgZoneID, int instFlag)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	int raidid = 0;

	// Find out what raid the character is in
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT raidid from raid_members where charid=%i", charID), errbuf, &result)) 
	{
		if (mysql_num_rows(result) == 1) 
		{
			row = mysql_fetch_row(result);
			raidid=atoi(row[0]);
			mysql_free_result(result);
			safe_delete_array(query);
			// Select the character IDs of the characters in the raid
			if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from raid_members where raidid=%i", raidid), errbuf, &result))
			{
				while((row = mysql_fetch_row(result))) 
				{
					charID = atoi(row[0]);
					setCharInstFlag(charID, orgZoneID, instFlag);
					Sleep(0);
				}
				safe_delete_array(query);
				mysql_free_result(result);
			}
		}
	}
	else
	{
		printf("Unable to get raid id: %s\n",errbuf);
		mysql_free_result(result);
		safe_delete_array(query);
	}
}

void Database::incrCurInstFlagNum(int instFlag)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	// Increment the curInstFlagNum
	instFlag++;
	if (instFlag > 9999)
		instFlag = 2000;

	if (RunQuery(query, MakeAnyLenString(&query, "UPDATE variables SET value=%i WHERE varname='curInstFlagNum'", instFlag), errbuf, &result))
	{
		safe_delete_array(query);
		mysql_free_result(result);
	}
	else 
	{
		cerr << "Error in incrCurInstFlagNum query '" << query << "' " << errbuf << endl;
		mysql_free_result(result);
		safe_delete_array(query);
	}
}

int Database::getCurInstFlagNum()
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	int instFlag = 0;

	// Get the current instant flag number
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'curInstFlagNum'"), errbuf, &result))
	{
		
		if (mysql_num_rows(result) == 1)
		{
			row = mysql_fetch_row(result);
			instFlag = atoi(row[0]);
			mysql_free_result(result);
			safe_delete_array(query);
			return instFlag;
		}
		else
		{
			cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
			mysql_free_result(result);
			safe_delete_array(query);
			return instFlag;
		}

	}
	else 
	{
		cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return instFlag;
	}
}
void Database::setCharInstFlag(int charID, int orgZoneID, int instFlag)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;

	if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET instZflagNum=%i, instZOrgID=%i WHERE id=%i", instFlag, orgZoneID, charID), errbuf, &result))
	{
		safe_delete_array(query);
		mysql_free_result(result);
	}
	else 
	{
		cerr << "Error in setCharInstFlagNum query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
}
Zone\zonedb.cpp
Append to the end
Code:
int32 ZoneDatabase::GetInstType(int32 zoneid) {
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT insttype FROM zone WHERE zoneidnumber=%i", zoneid), errbuf, &result))
	{
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1) {
			row = mysql_fetch_row(result);
			int8 tmp = atoi(row[0]);
			mysql_free_result(result);
			return tmp;

		}
		mysql_free_result(result);
	}

	else {
		cerr << "Error in GetInstType query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
	return 0;
}
bool ZoneDatabase::InstZoneLoaded(int32 charInstFlagNum){
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT zoneidnumber FROM zone WHERE zoneidnumber=%i", charInstFlagNum), errbuf, &result))
	{
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1) {
			return true;
		}
		else if (mysql_num_rows(result) == 0) {
			return false;
		}
		mysql_free_result(result);
	}

	else {
		cerr << "Error in isInstZoneLoad query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
	return 0;
}


//Copies original zones information into a new zone entry replacing the old zoneidnumber with the instflagnum
void ZoneDatabase::LoadInstZone(int32 target_zone_ID, int32 instFlagNum){
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	int32 affected_rows = 0;
	string tmpzonename = database.GetZoneName(target_zone_ID);
	string temp;
	const char* temp2;
	stringstream tmpFlag; // used for converting int32 instFlagNum to a string

	tmpFlag << instFlagNum;
	temp = tmpFlag.str();
	temp.append(tmpzonename);
	temp2 = temp.c_str();

	if (RunQuery(query, MakeAnyLenString(&query, "INSERT INTO zone (short_name, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, zoneidnumber, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer) SELECT '%s', file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, %i, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer FROM zone WHERE zoneidnumber =%i", temp2,instFlagNum,target_zone_ID), errbuf, 0, &affected_rows)){
		safe_delete_array(query);}
	else {
		cerr << "Error in LoadInstZone query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
}
Zone\zoneDB.cpp line 13 insert
Code:
#include <string>
#include <sstream>

Zone\zonedb.h
line 194 change const char* zone_name to int32 zoneid
Code:
bool	PopulateZoneSpawnList(int32 zoneid, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay = 0);
Zone\Zonedb.h
At the end of Zone Related around line 181
Code:
int32   GetInstType(int32 zoneid);
bool    InstZoneLoaded(int32 target_zone_ID);
void    LoadInstZone(int32 target_zone_ID, int32 InstFlagNum);

Zone.cpp Line 1146 change short_name to zoneid
Code:
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, delay))
Zone.cpp Line 779 change short_name to zoneid
Code:
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list))

Zone.cpp Line 772 change short_name to zoneid
Code:
else if (tmp == 0) {
	LogFile->write(EQEMuLog::Status, "No state saved, loading spawn2 points...");
	if (!database.PopulateZoneSpawnList(zoneid, spawn2_list))
	return false;
		}
Zone\Zone.cpp line 616 bottom of Zone::Shutdown insert
Code:
zone->ResetAuth();
	if (zone->GetZoneID() > database.GetDfltInstZFlag()){
		database.DeleteInstZone(zone->GetZoneID());
	}
	safe_delete(zone);
	dbasync->CommitWrites();
	UpdateWindowTitle();

Zone\spawn2.cpp line 226
Code:
bool ZoneDatabase::PopulateZoneSpawnList(int32 zoneid, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay) {
	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;
	
	const char *zone_name = database.GetZoneName(zoneid);
	int32 dfltInstZFlag = database.GetDfltInstZFlag();

	MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, timeleft, _condition, cond_value FROM spawn2 WHERE zone='%s'", zone_name);
	
	if (RunQuery(query, strlen(query), errbuf, &result))
	{
		safe_delete_array(query);
		while((row = mysql_fetch_row(result)))
		{
			Spawn2* newSpawn = 0;
			if (zoneid > dfltInstZFlag){
				newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), 0, atoi(row[8]), atoi(row[10]), atoi(row[11]));
			}
			else {
				newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), atoi(row[9]), atoi(row[8]), atoi(row[10]), atoi(row[11]));
			}
			//newSpawn->Repop(repopdelay);
			spawn2_list.Insert( newSpawn );
		}
		mysql_free_result(result);
	}
	else
	{
		LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query, errbuf);
		safe_delete_array(query);
		return false;
	}
	
	return true;
}
Zone\perlparser.cpp
Insert at the end around line 1884
Code:
newXS(strcpy(buf, "setinstflag"), XS__setinstflag, file);
newXS(strcpy(buf, "setinstflagmanually"), XS__setinstflagmanually, file);

Zone\perparser.cpp
insert around line 1758
Code:
XS(XS__setinstflag);
XS(XS__setinstflag)
{
	dXSARGS;
	if (items != 3)
		Perl_croak(aTHX_ "Usage: setinstflag(charID, orginalZoneID, type)");

	int		charID = (int)SvIV(ST(0));
	int		orgZoneID = (int)SvIV(ST(1));
	int		type = (int)SvIV(ST(2));

	quest_manager.setinstflag(charID, orgZoneID, type);

	XSRETURN_EMPTY;
}
XS(XS__setinstflagmanually);
XS(XS__setinstflagmanually)
{
	dXSARGS;
	if (items != 3)
		Perl_croak(aTHX_ "Usage: setinstflagmanually(charID, orginalZoneID, instFlag)");

	int		charID = (int)SvIV(ST(0));
	int		orgZoneID = (int)SvIV(ST(1));
	int		instFlag = (int)SvIV(ST(2));

	quest_manager.setinstflagmanually(charID, orgZoneID, instFlag);

	XSRETURN_EMPTY;
}



Zone\questmgr.h
Insert around line 151
Code:
	void setinstflag(int charID, int orgZoneID, int type);
	void setinstflagmanually(int charID, int orgZoneID, int instFlag);
Zone\questmgr.cpp
Insert at the end
Code:
void QuestManager::setinstflag(int charID, int orgZoneID, int type)
{
	int instFlag = database.getCurInstFlagNum();

	if (type == 0)
	{
		database.setCharInstFlag(charID, orgZoneID, instFlag);
		database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
	}
	else if(type == 1)
	{
		database.setGroupInstFlagNum(charID, orgZoneID, instFlag);
		database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
	}
	else if(type == 2)
	{
		database.setRaidInstFlagNum(charID, orgZoneID, instFlag);
		database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
	}
	else if(type == 3)
	{
		database.setCharInstFlag(charID, orgZoneID, instFlag);
		database.setGroupInstFlagNum(charID, orgZoneID, instFlag);
		database.setRaidInstFlagNum(charID, orgZoneID, instFlag);
		database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
	}
}

void QuestManager::setinstflagmanually(int charID, int orgZoneID, int instFlag)
{
	say("Got to start of setinstflagmanually");
	database.setCharInstFlag(charID, orgZoneID, instFlag);
}
Simple quest script to go with all this code.

Code:
sub EVENT_SAY { 
$charid = 0;
$charid = $client->CharacterID();
if($text=~/Hail/i){
	quest::say("Greetings traveler, Do you want to go play in Blackburrow?"); }
if($text=~/yes/i){
	quest::say("Oh wonderful! Do you want to play by yourself, in a group, or in a raid?"); }
if($text=~/self/i){
	quest::setinstflag($charid,17,0);
	quest::say("You can now go play in your own little Blackburrow world."); }
if($text=~/group/i){
	quest::say("Your party can now go play in their own little Blackburrow world.");
	quest::setinstflag($charid,17,1); }
if($text=~/raid/i){
	quest::say("Your raid can now go play in their only little Blackburrow world.");
	quest::setinstflag($charid,17,2); }
if($text=~/guess/i){
	quest::say("Your flags are set you can now go play in a Blackburrow world.");
	quest::setinstflag($charid,17,3); }
if($text=~/manually/i){
	quest::say("Okay your flag is set."); 
	quest::setinstflagmanually($charid,17,1500); }
}
Let me know if I missed something. I am going to go drink some beer.