View Single Post
  #6  
Old 09-10-2008, 05:08 AM
Rocker8956
Hill Giant
 
Join Date: Sep 2007
Posts: 117
Default

This code enables zone instancing (still needs work though)

Though it still requires a sql command to copy the zone information over, if you don't want to crash your server each time a zone gets added.

So here is how it works (run required SQL commands before doing this )
Select a zone you want to instance
Set that zone's insttype to 1
Select a character you want to access that zone
Set that character's
instZflagNum to a number greater than 1000
instZOrgID to the zoneID of the zone you picked
Run the following query
Code:
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 NEWZONESHORTNAME, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, instFlagNum, 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 = target_zone_ID)
replace NEWZONESHORTNAME with instZflagNum + shortname (see example)
replace instFlagNum with the instflagnum you chose
replace target_zone_id with the zone you chose to instance

zone character into the zone you picked.
rinse and repeat with second character changing the instZflagNum

K, here is my example
I want to instance blackburrow (has a zoneid of 17
I set blackburrow's insttype to 1 in the zone table
I want my toon MonkGod to access an instance of blackburrow
I set MonkGod's
instZflagNum to 1001
instZOrgID to 17

Run the following query
Code:
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 1001blackburrow, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, 1001, 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 = 17)

I replaced NEWZONESHORTNAME with 1001blackburrow
I replaced instFlagNum 1001
I replaced target_zone_id 17

I then repeat these step with Aries, my other character.
changing the instZflagNum to 1002

I doubt that made any sense but hopefully we can get the zone to be copied when the toon zones without it crashing the server. Currently the zone info gets copied to the database but the server crashes. With some tweaking all that would be required is a quest command that sets a characters InstZflagNum and instZOrgID.

Anyhow here is the required changes. This was done against 1129 using PEQ database.
Please let me know what bugs you notice.

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', 1000, 'Character:curInstFlagNum', '2008-09-05 04:46:47');
INSERT INTO rule_values VALUES (0,'World:dfltInstZflag',1000);
Zoneserver.cpp
Near Line 482
Code:
if(GetZoneID() == ztz->current_zone_id)	// this is a request from the egress zone
			{
				zlog(WORLD__ZONE,"Processing ZTZ for egress from zone for client %s\n", ztz->name);

				if
				(
					ztz->admin < 80 &&
					ztz->ignorerestrictions < 2 &&
					zoneserver_list.IsZoneLocked(ztz->requested_zone_id)
				)
				{
					ztz->response = 0;
					SendPacket(pack);
					break;
				}

				ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);
				ZoneServer *ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id);
				if(ingress_server)	// found a zone already running
				{
					_log(WORLD__ZONE,"Found a zone already booted for %s\n", ztz->name);
					ztz->response = 1;
				}
				else	// need to boot one
				{
					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))){
						_log(WORLD__ZONE,"Successfully booted a zone for %s\n", ztz->name);
						// bootup successful, ready to rock
						ztz->response = 1;
						ingress_server = zoneserver_list.FindByID(server_id);
Client.cpp
Line 644 EnterWorld(bool TryBootup)
Code:
void Client::EnterWorld(bool TryBootup) {
	//int16 zone_port;
	//char zone_address[255];
	if (zoneID == 0)
		return;
	zoneID = database.GetInstZoneID(zoneID, GetCharName());
	ZoneServer* zs = zoneserver_list.FindByZoneID(zoneID);
	const char *zone_name=database.GetZoneName(zoneID, true);
Zoning.cpp
Please note this code will crash your server if the zone is not already in your database
Line 125
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())
	{
		if (target_zone_id != database.GetCharInstFlagNum(characterID)){
			int32 charInstZOrgID = database.GetCharInstZOrgID(characterID);
			// Does character's instance flag match the zone he/she is trying to access
			if(charInstZOrgID != target_zone_id)
			{
				Message(13, "No access flag to target instanced zone.");
				SendZoneCancel(zc); // zoning.cpp line 130
				return;
			}
			// 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;
			}
		}
	}
}
Database.h
Near Line 181
Code:
int32   GetDfltInstZFlag();
Near Line 197
Code:
int32   GetInstZoneID(int32 zoneID, const char* charName);
Near Line 202
Code:
int32	GetCharInstFlagNum(int32 charID);
Near Line 203
Code:
int32	GetCharInstZOrgID(int32 charID);
Database.cpp
Line 1173 Replace Database::GetZoneName with
Code:
const char* Database::GetZoneName(int32 zoneID, bool ErrorUnknown) {
	if (zonename_array == 0) {
		if (ErrorUnknown)
			return "UNKNOWN";
		else
			return 0;
	}
	if (zoneID <= max_zonename) {
		if (zonename_array[zoneID])
			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);
				}
			}
			return zonename_array[zoneID];
	}
	else {
		if (ErrorUnknown)
			return "UNKNOWN";
		else
			return 0;
	}
	
	
	if (ErrorUnknown)
		return "UNKNOWN";
	return 0;
}
Line: End of database.cpp
Code:
int32 Database::GetDfltInstZFlag(){
char errbuf[MYSQL_ERRMSG_SIZE];
   	 char *query = 0;
   	 MYSQL_RES *result;
   	 MYSQL_ROW row;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT rule_value FROM rule_values WHERE rule_name = 'World: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);
}
Zonedb.cpp
Code:
#include <string>
#include <sstream>
Append to the end Zonedb.cpp
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);
		// Reloads zone names since one was added
		if(database.LoadZoneNames());
	}
	else {
		cerr << "Error in LoadInstZone query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
}
Zonedb.h
Line 169 at the end of Zone Related
Code:
	int32   GetInstType(int32 zoneid);
	bool    InstZoneLoaded(int32 target_zone_ID);
	void    LoadInstZone(int32 target_zone_ID, int32 InstFlagNum);
Reply With Quote