spider661 |
09-28-2008 08:37 PM |
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?
|