Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bug Reports

Development::Bug Reports Post detailed bug reports and what you would like to see next in the emu here.

Reply
 
Thread Tools Display Modes
  #16  
Old 09-12-2008, 12:32 AM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

any chance you could post maybe a diff file or what lines i should and where so i can see whats wrong maybe? i really want to get this fixed soon... im using a version one guy posted with some bot code in it and im not sure how to move all that code over.. i wish someone would go though and comment this code for bots/ bot code stops here lol.. or post a diff file for the bot code.. anyways.. whats the chances of getting a few debug lines i can put in myself for now?
Reply With Quote
  #17  
Old 09-12-2008, 01:04 AM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

ZoneDatabase::RefreshGroupFromDB in zonedb.h is probably where it's occuring it's not safe at all, I'm gonna go back and redo it.
Reply With Quote
  #18  
Old 09-28-2008, 08:37 PM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

ok i found the problem its in my bot code can anyone see if they can help me fix it?

Code:
void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {

#ifdef EQBOTS

	// EQoffline: Remove the group if the leader is grouped
	Mob *clientmob = CastToMob();
	if(clientmob) {
		int16 cmid = clientmob->GetID();
		if(clientmob->IsBotRaiding()) {
			BotRaids* br = entity_list.GetBotRaidByMob(clientmob);
			if(br) {
				br->RemoveRaidBots();
				br = NULL;
			}
		}
		if(clientmob->IsGrouped()) {
			Group *g = entity_list.GetGroupByMob(clientmob);
			if(g) {
				for(int i=5; i>=0; i--) {
					if(g->members[i] && g->members[i]->IsBot()) {
						g->members[i]->Kill();
					}
				}
				if(g->BotGroupCount() <= 1) {
					g->DisbandGroup();
				}
			}
		}
		database.CleanBotLeader(cmid);
	}

#endif //EQBOTS

	zoning = true;
	if (app->size != sizeof(ZoneChange_Struct)) {
		LogFile->write(EQEMuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct));
		return;
	}

#if EQDEBUG >= 5
	LogFile->write(EQEMuLog::Debug, "Zone request from %s", GetName());
	DumpPacket(app);
#endif
	ZoneChange_Struct* zc=(ZoneChange_Struct*)app->pBuffer;

	uint16 target_zone_id = 0;
	ZonePoint* zone_point = NULL;

	//figure out where they are going.
	if(zc->zoneID == 0) {
		//client dosent know where they are going...
		//try to figure it out for them.
		
		switch(zone_mode) {
		case EvacToSafeCoords:
		case ZoneToSafeCoords:
			//going to safe coords, but client dosent know where?
			//assume it is this zone for now.
			cheat_timer.Start(35000,false);
			target_zone_id = zone->GetZoneID();
			break;
		case GMSummon:
			target_zone_id = zonesummon_id;
			break;
		case GateToBindPoint:
			target_zone_id = m_pp.binds[0].zoneId;
			break;
		case ZoneToBindPoint:
			target_zone_id = m_pp.binds[0].zoneId;
			break;
		case ZoneSolicited:  //we told the client to zone somewhere, so we know where they are going.
			cheat_timer.Start(35000,false);
			target_zone_id = zonesummon_id;
			break;
		case ZoneUnsolicited:   //client came up with this on its own.
			zone_point = zone->GetClosestZonePointWithoutZone(GetX(), GetY(), GetZ(), ZONEPOINT_NOZONE_RANGE);
			if(zone_point) {
				//we found a zone point, which is a reasonable distance away
				//assume that is the one were going with.
				target_zone_id = zone_point->target_zone_id;
			} else {
				//unable to find a zone point... is there anything else
				//that can be a valid un-zolicited zone request?
				
				CheatDetected(MQZone);
				Message(13, "Invalid unsolicited zone request.");
				LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
				SendZoneCancel(zc);
				return;
			}
			break;
		};
	}
	else {
		// This is to allow both 6.2 and Titanium clients to perform a proper zoning of the client when evac/succor
		// WildcardX 27 January 2008
		if(zone_mode == EvacToSafeCoords && zonesummon_id > 0)
			target_zone_id = zonesummon_id;
		else
		target_zone_id = zc->zoneID;
		
		//if we are zoning to a specific zone unsolicied,
		//then until otherwise determined, they must be zoning
		//on a zone line.
		if(zone_mode == ZoneUnsolicited) {
			zone_point = zone->GetClosestZonePoint(GetX(), GetY(), GetZ(), target_zone_id, ZONEPOINT_ZONE_RANGE);
			//if we didnt get a zone point, or its to a different zone,
			//then we assume this is invalid.
			if(!zone_point || zone_point->target_zone_id != target_zone_id) {
				Message(13, "Invalid unsolicited zone request.");
				LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
				if ((cheat_timer.GetRemainingTime())<1 || (!cheat_timer.Enabled())){ //Lieka:  Disable MQGate Detector if timer is active.
					CheatDetected(MQGate);
				}					
				SendZoneCancel(zc);
				return;
			}
		}
	}


	//make sure its a valid zone.
	const char *target_zone_name = database.GetZoneName(target_zone_id);
	if(target_zone_name == NULL) {
		//invalid zone...
		Message(13, "Invalid target zone ID.");
		LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id);
		SendZoneCancel(zc);
		return;
	}

	//load up the safe coords, restrictions, and verify the zone name
	float safe_x, safe_y, safe_z;
	sint16 minstatus = 0;
	int8 minlevel = 0;
	char flag_needed[128];
	if(!database.GetSafePoints(target_zone_name, &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) {
		//invalid zone...
		Message(13, "Invalid target zone while getting safe points.");
		LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name);
		SendZoneCancel(zc);
		return;
	}

#ifdef EMBPERL
		char buf[10];
		snprintf(buf, 9, "%d", target_zone_id);
		buf[9] = '\0';
		((PerlembParser*)parse)->Event(EVENT_ZONE, 0, buf, (NPC*)NULL, this);
#endif

	//handle circumvention of zone restrictions
	//we need the value when creating the outgoing packet as well.
	int8 ignorerestrictions = zonesummon_ignorerestrictions;
	zonesummon_ignorerestrictions = 0;

	float dest_x=0, dest_y=0, dest_z=0, dest_h;
	dest_h = GetHeading();
	switch(zone_mode) {
	case EvacToSafeCoords:
	case ZoneToSafeCoords:
		LogFile->write(EQEMuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id);
		dest_x = safe_x;
		dest_y = safe_y;
		dest_z = safe_z;
		break;
	case GMSummon:
		dest_x = zonesummon_x;
		dest_y = zonesummon_y;
		dest_z = zonesummon_z;
		ignorerestrictions = 1;
		break;
	case GateToBindPoint:
		dest_x = m_pp.binds[0].x;
		dest_y = m_pp.binds[0].y;
		dest_z = m_pp.binds[0].z;
		break;
	case ZoneToBindPoint:
		dest_x = m_pp.binds[0].x;
		dest_y = m_pp.binds[0].y;
		dest_z = m_pp.binds[0].z;
		ignorerestrictions = 1;	//can always get to our bind point? seems exploitable
		break;
	case ZoneSolicited:  //we told the client to zone somewhere, so we know where they are going.
		//recycle zonesummon variables
		cheat_timer.Start(3500,false);
		dest_x = zonesummon_x;
		dest_y = zonesummon_y;
		dest_z = zonesummon_z;
		break;
	case ZoneUnsolicited:   //client came up with this on its own.
		//client requested a zoning... what are the cases when this could happen?
		
		//Handle zone point case:
		if(zone_point != NULL) {
			//they are zoning using a valid zone point, figure out coords
			
			//999999 is a placeholder for 'same as where they were from'
			if(zone_point->target_x == 999999)
				dest_x = GetX();
			else
				dest_x = zone_point->target_x;
			if(zone_point->target_y == 999999)
				dest_y = GetY();
			else
				dest_y = zone_point->target_y;
			if(zone_point->target_z == 999999)
				dest_z=GetZ();
			else
				dest_z = zone_point->target_z;
			if(zone_point->target_heading == 999)
				dest_h = GetHeading();
			else
				dest_h = zone_point->target_heading;
			
			break;
		}
		
		//for now, there are no other cases...
		
		//could not find a valid reason for them to be zoning, stop it.
		CheatDetected(MQZone);
		Message(13, "Invalid unsolicited zone request.");
		LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name);
		SendZoneCancel(zc);
		return;
	};

	//OK, now we should know where were going...

	//Check some rules first.
	sint8 myerror = 1;		//1 is succes

	//not sure when we would use ZONE_ERROR_NOTREADY

	//enforce min status and level
	if (!ignorerestrictions && (Admin() < minstatus || GetLevel() < minlevel)) {
		cheat_timer.Start(3500,false); //Lieka:  Don't set off warp detector for when a player is moved to the safe-spot for trying to access a zone without the appropriate level or status requirements (i.e. zoning into FearPlane at level 30, etc)
		myerror = ZONE_ERROR_NOEXPERIENCE;
		}
	
	if(!ignorerestrictions && flag_needed[0] != '\0') {
		//the flag needed string is not empty, meaning a flag is required.
		if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(target_zone_id)) {
			Message(13, "You must have the flag %s to enter this zone.");
			myerror = ZONE_ERROR_NOEXPERIENCE;
			cheat_timer.Start(3500,false);
		}
	}
	
	//Enforce ldon doungeon entrance rules
	if(myerror == 1 && database.IsLDoNDungeon(target_zone_id)
	// && !ignorerestrictions
	) {
		//this zone is an ldon dungeon
		int advid = GetAdventureID();
		if(advid > 0){
			//we are in an adventure... make sure its the right one
			AdventureInfo ai = database.GetAdventureInfo(advid);
			if(target_zone_id != ai.zonedungeonid) {
				Message(13, "You are not allowed to enter this dungeon!");
				LogFile->write(EQEMuLog::Error, "Zoning %s: Not allowed to enter dungeon '%s' (%d). Not in the right adventure.", GetName(), target_zone_name, target_zone_id);
				SendZoneCancel(zc);
				return;
			}
		} else {
			Message(13, "You are not allowed to enter this dungeon!");
			LogFile->write(EQEMuLog::Error, "Zoning %s: Not allowed to enter dungeon '%s' (%d). Not in any adventure.", GetName(), target_zone_name, target_zone_id);
			SendZoneCancel(zc);
			return;
		}
	}

	if(myerror == 1) {
		//we have successfully zoned
		DoZoneSuccess(zc, target_zone_id, dest_x, dest_y, dest_z, dest_h, ignorerestrictions);
	} else {
		LogFile->write(EQEMuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name);
		SendZoneError(zc, myerror);
	}
}
the problem is the remove bots call if i comment it out and don't have bots the group stays intact if i have bots it destroys the group on zoneing and leaves the bots in the last zone.

so i cant just comment it out i have to fix it.

any suggestions?
Reply With Quote
  #19  
Old 09-29-2008, 02:40 AM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

got this fixed now.. look at the bot code post to see how.
Reply With Quote
Reply


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 03:59 PM.


 

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